在使用单调栈时我认为需要先想好下面这几个问题:
- 什么时候使用单调栈?
在寻找下一个比其小/大的元素时 - 单调栈的基本逻辑是什么?
保持栈内元素的单调性,注意这里是“值”的单调,而不一定是栈内元素的单调,每日温度的题目中,栈内的元素其实是下标,而需要保持单调的是下标对应的值。
以单调增为例:要保证从栈顶到栈底为单调增,单调栈中新元素一定要入栈,同时要保证单调增,因此要把小于新元素的栈顶元素都出栈。
简单的说,新元素入栈前,对栈顶进行出栈,直到栈顶元素大于新元素,伪代码如下:
newvalue
# 当栈非空以及栈顶元素小于新元素,则需要出栈
while stack and stack[-1]<newvalue:
stack.pop()
# 检查完毕后入栈
stack.append(newvalue)
-
我需要得到的结果是什么
结果一般是在元素出栈时进行计算,这里需要根据问题来思考我要的是什么,具体的我将会在下面对不同的题目进行分析 -
如何理解单调栈
栈内元素为待处理元素,每出栈一次,相当于得到出栈值下标对应的结果
1、接雨水
力扣链接
这里只是简单的的分享我的思路,具体的解题步骤可以参考《代码随想录》里的图片,大家可以在看完后在这里重新看看我的理解
我们使用单调栈来计算,也就是按行计算,看下图的①号图,水往低处流,在一个 前高 中低 后高 的坑中一定是有水的,如红色三角形示意。
Python完整代码:
class Solution:
def trap(self, height: List[int]) -> int:
# 使用单调栈
stack = [0] # 栈内的元素为下标
res = 0
# 我要的结果是体积,关键就是体积如何计算
# 注意在单调栈中,结果的计算只在弹出栈的时候计算
# 高h = min(待加入元素,栈顶的下一个元素) - 栈顶元素 注意一定是大于0的 因为‘栈顶的下一个元素’>栈顶元素
# 待加入元素 > 栈顶元素
# 底w = 待加入元素下标-栈顶的下一个元素的下标-1
# res = h*w
# 开始遍历
for i in range(1,len(height)):
# 检查 栈顶元素和待加入元素
while stack and height[stack[-1]] <= height[i]:
t = stack.pop() # 当栈顶小于等于 必须要弹出
if height[t] == height[i]: # 等于时不操作
continue
elif stack and height[t] < height[i]: # 栈内还有元素切小于待加入元素时,开始计算
h = min(height[i],height[stack[-1]]) - height[t]
w = i - stack[-1] -1
res+=h*w
# 最后加入待加入元素
stack.append(i)
return res
学习《代码随想录》的笔记记录,欢迎大家支持原作者:https://www.programmercarl.com/
代办:
- 单调队列的对比