给定一个数组,找出每个元素的最后一个较小的元素

Posted

技术标签:

【中文标题】给定一个数组,找出每个元素的最后一个较小的元素【英文标题】:Given an array, find out the last smaller element for each element 【发布时间】:2017-09-12 19:03:47 【问题描述】:

给定一个数组,找到每个元素在数组中的最后一个较小元素的索引。

例如,假设给定的数组是4,2,1,5,3。然后每个元素的最后一个较小的元素将如下所示。

4->3
2->1
1->Null
5->3
3->Null

注意第一对 4->3,3 是数组中最后一个小于 4 的元素。

结果/输出数组将具有索引而不是元素本身。结果将是4,2,-1,4,-1

我在一次采访中被问到这个问题,但我想不出比琐碎的O(n^2) 解决方案更好的解决方案。

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我们需要对所有具有较小值的元素计算max(index)

让我们按字典顺序对对(元素、索引)进行排序并遍历它们,以跟踪迄今为止看到的最大索引。这正是最右边的较小元素的位置。以下是如何实现它:

def get_right_smaller(xs):
    res = [-1] * len(xs)
    right_index = -1
    for val, idx in sorted((val, idx) for idx, val in enumerate(xs)):
        res[idx] = right_index if right_index > idx else -1
        right_index = max(right_index, idx)
    return res

即使输入数组包含相同的数字,此解决方案也能正常工作,因为如果两个元素的值相同,则具有较小索引的元素会更早。

此解决方案的时间复杂度为O(N log N + N) = O(N log N)(它进行排序和一次线性传递)。

如果数组的所有元素都是O(N),则可以使用计数排序使此解线性化。

【讨论】:

很好的解决方案!【参考方案2】:
Make a list, add last element index. 
Walk through array right to left.     
For every element:
   if list tail value is smaller then current element
       find the most first smaller list element (binary search, list is sorted)
   otherwise 
       add element index to the list tail, output -1

对于4,2,1,5,3,6,2,示例列表将包含index 6 (value 2); index 2 (value 1)

【讨论】:

以数组为例 - 4,2,1,5,3,6,2。当我从右边处理时。添加后 3,6,2 - 3(root) 2(Left) 6(right) 现在添加 3,6,2 后,对于元素 5,我们将查看树(在插入 5 之前)。 2 存在较小的值 - 3 和 2。选择的正确值是 2,但如果我使用 floor 函数,那么它会给我 3。那么我们如何选择较小的值? 看来我理解条件last smaller element 错误。 添加了新方法。

以上是关于给定一个数组,找出每个元素的最后一个较小的元素的主要内容,如果未能解决你的问题,请参考以下文章

在数组中的每个项目之前有多少个连续元素较小

给定一个唯一正整数数组,为每个元素找到最近的较小元素,但距离至少为 k

对于给定的n个元素的数组a[1..n] 要求从中找出第k小的元素,输出这个元素 pascal

C语言 对于给定的N各元素的数组[0;N-1],要求从中找出第K小的元素

求包含每个有序数组(共k个)至少一个元素的最小区间

给定一个数组,对于每个元素,找出小于它的元素的总数,它们出现在它的右侧