单调栈问题:
要知道单调栈的适用于解决什么样的问题,首先需要知道单调栈的作用。单调栈分为单调递增栈和单调递减栈,通过使用单调栈我们可以访问到下一个比他大(小)的元素(或者说可以)。
也就是说在队列或数组中,我们需要通过比较前后元素的大小关系来解决问题时我们通常使用单调栈。下面我们通过简单介绍单调减栈和单调增栈问题来进一步说明使用单调栈处理问题的过程。
什么时候使用单调栈?
通常是一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素,且要求 O(n) 的时间复杂度
单调栈原理:
单调递增栈:从 栈底 到 栈顶 递增,栈顶大
单调递减栈:从 栈底 到 栈顶 递减,栈顶小
python模板套路:
1): 当前项向右找第一个比自己大的位置 —— 从右向左维护一个单调递减栈。
def nextGreaterElement_01(nums: list):
length = len(nums)
res, stack = [-1] * length, []
for i in range(length - 1, -1, -1):
while stack and stack[-1] <= nums[i]:
stack.pop()
if stack:
res[i] = stack[-1]
stack.append(nums[i])
return res
或者 当前项向右找第一个比自己大的位置 —— 从左向右维护一个单调递减栈。
def nextGreaterElement_011(nums: list):
length = len(nums)
res, stack = [-1] * length, []
for i in range(length):
while stack and nums[stack[-1]] < nums[i]:
idx = stack.pop()
res[idx] = nums[i]
stack.append(i)
return res
2):当前项向右找第一个比自己小的位置 —— 从右向左维护一个单调递增栈
def nextGreaterElement_02(nums: list):
length = len(nums)
res, stack = [-1] * length, []
for i in range(length - 1, -1, -1):
while stack and stack[-1] >= nums[i]:
stack.pop()
if stack:
res[i] = stack[-1]
stack.append(nums[i])
return res
3): 当前项向左找第一个比自己大的位置 —— 从左向右维护一个单调递减栈
def nextGreaterElement_03(nums: list):
length = len(nums)
res, stack = [-1] * length, []
for i in range(length):
while stack and stack[-1] <= nums[i]:
stack.pop()
if stack:
res[i] = stack[-1]
stack.append(nums[i])
return res
4): 当前项向左找第一个比自己小的位置 —— 从左向右维护一个单调递增栈
def nextGreaterElement_04(nums: list):
length = len(nums)
res, stack = [-1] * length, []
for i in range(length):
while stack and stack[-1] >= nums[i]:
stack.pop()
if stack:
res[i] = stack[-1]
stack.append(nums[i])
return res