📅  最后修改于: 2023-12-03 15:37:41.539000             🧑  作者: Mango
有时候在使用数组时,我们需要查找数组中的下一个更大的元素。但是,在圆形数组中进行这个操作会更加具有挑战性。
本文介绍两套算法来在圆形数组中查找下一个更大的元素。
想要在圆形数组中查找下一个更大的元素,最直接的方法就是暴力法。
暴力法基于两个观察:
考虑到数组可能是圆形的,我们可以顺时针遍历圆形数组两次。
def nextGreaterElements(nums) -> List[int]:
n = len(nums)
res = [-1] * n
stack = []
for i in range(2 * n):
while stack and nums[stack[-1]] < nums[i % n]:
res[stack.pop()] = nums[i % n]
if i < n:
stack.append(i)
return res
这里我们用res列表存放答案,用stack存放当前最大的元素的下标,用while循环来找到比当前元素更大的元素并更新答案和stack。
算法的时间复杂度是O(n^2),因为数组可能需要遍历两次。空间复杂度是O(n),因为用了stack数组。
一个更高效的方法是使用单调栈。
首先我们需要明白一个事实:在找到当前元素的下一个更大的元素后,以后再遇到的元素就不必再进行判断了。
因此我们可以对数组进行两次单调栈操作:第一次遍历数组时,用单调栈找到所有元素的下一个更大的元素;第二次遍历数组时,用单调栈找到除了第一次找到的下一个更大的元素以外的下一个更大的元素。
def nextGreaterElements(nums) -> List[int]:
n = len(nums)
res = [-1] * n
stack = []
for i in range(n*2-1, -1, -1): # 第 2/n 次遍历数组
while stack and nums[stack[-1]] <= nums[i % n]:
stack.pop() # pop所有比nums[i%n]小的元素
res[i % n] = -1 if not stack else nums[stack[-1]]
stack.append(i % n) # push当前元素
return res
这里我们同样用res数组存放答案,用stack数组存放单调递减的元素的下标。
注意在第二次遍历数组时,要先将元素下标加上n,这样可以让上一次处理到的下标在当前数组中只出现一次。
算法的时间复杂度是O(n),因为只需要遍历两次数组,同时空间复杂度是O(n),因为使用了stack数组。
在圆形数组中查找下一个更大的元素需要考虑到边界问题,同时需要用到单调栈的方法,在效率和稳定性上都要优于暴力法。
以上就是两套算法的具体实现,希望对读者有所帮助。