我得到了一个数组。我需要为数组中的每个元素找到最后一个(最右边的)较小或相等的数字。
例如:
2 5 1 6 4 7
2的最后一个小于或等于数字1,
5的最后一个较小或等于4的数字,而不是1,等等。
另一个例子:
5 100 8 7 6 5 4 3 2 1
在这里,每个元素的最后一个较小或等于1。我知道幼稚的方法,即O(n²),但需要更好的方法。
答案 0 :(得分:4)
您可以从右到左构建一个最小数量的最小数组,直到现在。
对于您的示例2 5 1 6 4 7
,它将是:
从最右边的位置开始:
7
4 7 (4 < 7)
4 4 7 (6 > 4)
...
因此,您的示例的最小数组为:1 1 1 4 4 7
现在,对于每个查询,您都将从min数组中的相同位置开始,然后一直走到找到一个更大的数字为止
对于2:
2 5 1 6 4 7
1 1 1 4 4 7
^
------^
第一个大于2的元素为4,因此返回数字等于= 1
对于5:
2 5 1 6 4 7
1 1 1 4 4 7
^
----------^
第一个大于5的元素为7,因此返回数字等于= 4
要有效地查找输入数组中每个元素的第一个更大的元素,可以使用upper_bound算法(在C ++ http://www.cplusplus.com/reference/algorithm/upper_bound/中为例)来查找第一个更大的元素
Upper_bound需要log(N)时间,因此处理输入数组中每个元素的总时间为O(NlogN)
最小数组的内存复杂度是线性的