📅  最后修改于: 2023-12-03 15:26:11.383000             🧑  作者: Mango
当我们处理一个数组时,有时候我们想知道数组中每个元素左侧的最近的最大值或者相同值,以此来解决某些问题。这个问题涉及到算法和数据结构中的一个重要概念:单调栈。
单调栈是一个栈,它在任意时刻保持栈内元素单调递增或递减,通常是单调递增。当一个元素要入栈时,我们先把栈顶比它小的元素全都弹出栈顶,这样就能保证栈是单调递增的了。这个时候,新元素不用和栈中其他元素比较,只需要和栈顶比较就可以了。如果新元素比栈顶大,那么栈顶元素的左边第一个比它大的数就是新元素了。这个过程可以用一个简单的例子来说明。
假设我们要解决这个问题:给定一个数组,求每个元素左边的最近的最大值或相同值。
代码如下:
def left_largest_or_equal(nums):
stack = []
res = []
for i in range(len(nums)):
while (stack and nums[stack[-1]] < nums[i]):
stack.pop()
if not stack:
res.append(-1)
else:
res.append(nums[stack[-1]])
stack.append(i)
return res
这里使用一个栈来存放数组的下标,我们需要遍历这个数组,每遍历到一个元素,我们就要找到它左边的最近的最大值或相同值。我们可以先将第一个元素的下标入栈,然后遍历整个数组。当遍历到一个新的元素时,如果栈为空,说明这个新元素左边没有比它大的数字了,此时我们将-1作为左边最近的最大值或相同值添加到结果数组中。如果栈不为空,我们就要判断栈顶元素对应的数字是否小于当前元素对应的数字,如果小于,栈顶元素出栈,继续判断栈顶元素是否比当前元素小,直到栈为空或栈顶元素比当前元素大。如果栈为空,说明新元素左边没有比它大的数字了,此时我们也将-1作为左边最近的最大值或相同值添加到结果数组中。如果栈不为空,说明新元素左边最近的最大值或相同值就是栈顶元素所对应的数字。
输入:[3, 2, 5, 6, 9, 8]
输出:[-1, 3, 3, 5, 6, 6]
单调栈是一个非常实用的算法,它可以解决很多问题。这个算法的时间复杂度是O(n),空间复杂度也是O(n)。如果我们需要求每个元素右边的最近的最大值或相同值,可以使用单调递减的栈来处理。