从给定的输入数组中,对于每个元素,找到每个数组中存在的下一个更高元素。例如,{40,50,11,32,55,68,75}
输出应为{50,55,32,55,68,75,-1}
。对于元素,如果不存在更高元素,则打印-1。
复杂性应小于O(n^2)
。您可以使用数据结构而不限制空间复杂性。
答案 0 :(得分:35)
您可以使用堆栈,时间复杂度为 O(N)
。
算法:
从左侧开始向右移动。当你从数组中选择一个元素时(比方说x),弹出Stack直到Stack中的元素(比如说y)有一个大于数组元素的元素,即x>年。然后推动元素即x叠加。
e.g。 {40,50,11,32,55,68,75}
。这里s
是堆栈。
s: 40
50,如s.peek()< 50 pop 40(40的大元素是50)然后按50 s: 50
下一个更高的元素40 - 50。
11,s.peek()> 11所以推11. [{1}}
32,s.peek()< 32,所以弹出元素,现在它是50,大于32因此推32.。s: 50, 11
55,s.peek()< 55,所以弹出元素,即32然后弹出下一个以及50< 55,然后按55.下一个更高的元素11 - 32。
s: 50 ,32
。
下一个更高的元素是32 - 55。
下一个更高的元素50 - 55。
68,s.peek()< 68所以弹出它并推动68. s: 55
75,s.peek()< 75弹出它然后推75 s: 68
。
下一个更高的元素68 - 75。
由于数组没有任何元素,因此不会弹出堆栈,表示数组中的所有元素都没有更大的元素,即-1。
下一个更高的元素是75 - -1。
代码中的相同算法:
s:75
答案 1 :(得分:3)
在输出55的输入55中看到的问题的关键属性是,您显然只需要在输入序列中之后 输入元素之后的那些更大的元素。否则,此时的输出将为40。
我建议你从右边处理数组,并维护一个看到元素的树(例如红黑树)。对于您处理的每个元素,首先在O(log n)中搜索树以获取下一个更大的元素。您将其存储在O(1)中以获得要在末尾打印的结果,然后将当前处理的元素插入到O(log n)中的树中。在O(n log n)中以这种方式处理所有元素,然后反转你在O(n)中输出的事物列表,你就完成了。
答案 2 :(得分:-4)
这很容易:
1.对数组进行排序。 O(n log n)
2.在排序数组中找到每个元素(索引i),并在右侧选择元素或-1。使用二进制搜索是O(log n),对于每个元素,它是O(n log n)
这可能有效(在C#中):
IEnumerable<int> NextNumber (int[] numbers)
{
var sorted = numbers.OrderBy(n => n).ToList();
int cnt = numbers.Count()-1;
return numbers.Select(sorted.BinarySearch).Select(i => i == cnt ? -1 : sorted[i + 1]);
}
编辑:如果请求的结果严格要求下一个更高的元素,无论相对顺序如何,此解决方案都有效。