在未排序的数组中,我们必须用大于当前元素的右边的第一个元素替换每个元素。如果右边的元素都不大,则应将其替换-1。
-1
例:
3 1 2 5 9 4 8 should be converted to 5 2 5 9 -1 8 -1
我可以想到一个简单的解决方案,其中我们检查整个数组中的每个元素,这是一个 Ο(n²) 解决方案。有一个更好的方法吗?
主要思想是以相反的顺序(从右到左)处理数组。我们进行一些观察:
A[k] ≤ A[j]
A[i+1..n-1]
在您的示例中,相关元素的顺序是从右到左:
[] [8] [4,8] [9] [5,9] [2,5,9] [1,5,9]
它看起来像一个堆栈,我们确实可以使用堆栈来维护迭代之间的顺序。
在处理新元素时,我们首先需要找到数组元素的结果。观察结果是结果是堆栈上的最高元素, 未被 新元素使之无效。因此,我们可以从堆栈中弹出所有无关的元素。然后,最重要的是我们的结果。然后,我们可以推送新元素,因为它与我们的定义相关。
stack = [] A = [3, 1, 2, 5, 9, 4, 8] result = [-1]*len(A) for i := len(A) - 1 to 0: # remove all elements made irrelevant by A[i] while not stack.empty() && stack.top() <= A[i]: stack.pop() # now the top of the stack is the result for index i if not stack.empty(): R[i] = stack.top() # push the new element on the stack. The stack will still contain all relevant # elements in increasing order from top to bottom stack.push(A[i])
迭代的循环不变式为i“ stack 包含索引右边的相关元素的子序列i ”。易于验证,并暗示该算法的正确性。
i
stack
每个元素最多被推送和弹出一次,因此我们的总运行时间为 Ο(n) 。