以下是leetcode 42原题:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
此题使用单调栈解决,配合下面我画的图,比较容易理解一点,我这里用了示例2的height来作解释:
具体来说,单调栈的步骤如下:
- 先将第一个元素压入栈,此时栈内才不为空
- 如果height后面的元素小于前面入栈的元素,则可以顺序入栈
- 如果 出现了大的元素,超过前一个入栈的元素,就要开始收集雨水了,图中蓝色小点部分为收集到的雨水。
- 将此时的栈顶元素,就是相对于大元素来说较小的元素,弹出,并用cur来接收它,后面计算还要用到这个值
- 收集雨水的高度为:min(此时的大元素,和cur前的那个元素的最小值)-cur的高度
- 收集雨水的宽度为:大元素下标-cur前那个元素的下标-1
- 我们将height的下标记录在stack数组中,雨水的结果保存在res中
对应的python代码如下:
def trap(height:list):
stack=[]
res=0
for i in range(len(height)):
while stack and height[i]>height[stack[-1]]:
cur=stack.pop()
if not stack:
break
h=min(height[i],height[stack[-1]])-height[cur]
w=i-stack[-1]-1
res+=h*w
stack.append(i) #记录height的下标位置
return res