题目描述:
思路分析
本题思路与之前的84,239题目一样采用单调栈(队列)的具体的思路可以参见 ![链接文章](https://www.jianshu.com/p/89559e36ebe5)之前的文章。这里不再赘述。这里主要想描述一下具体运行过程当中栈的变化情况,一旦明确了算法的具体执行过程则运算代码即可应运而生。具体栈的运行过程如下表格展示:
数组 内容 | 栈操作 | 单调之前减栈区内容 | 操作之后栈区内容 | 操作内容 | 计算 记录 | |
---|---|---|---|---|---|---|
顺序 | ||||||
1 | 0 | 0入栈 | 0, | |||
2 | 1 | 1入栈0出栈 | 0, | 1, | 如果出栈是栈顶的话计算雨量 | 0 |
3 | 0 | 0入栈 | 1, | 1,0 | ||
4 | 2 | 2入栈之前出栈 | 1,0 | 2, | 遇到栈顶栈顶 | 1 |
5 | 1 | 1入栈 | 2, | 2,1 | ||
6 | 0 | 0入栈 | 2,1 | 2,1,0 | ||
7 | 1 | 1入栈之前比他小出栈 | 2,1,0 | 2,1,1 | ||
8 | 3 | 3入栈之前比他小出栈 | 2,1,1 | 3, | 遇到栈顶2开始计算降雨量 | 4 |
9 | 2 | 2入栈 | 3, | 3,2 | ||
10 | 1 | 1入栈 | 3,2 | 3,2,1 | ||
11 | 2 | 2入栈之前小的出栈 | 3,2,1 | 3,2,2 | ||
12 | 1 | 1入栈 | 3,,2,2 | 3,2,2,1 | 开始弹栈 | |
13 | 弹出1 | 3,2,2 | 计算2-1的雨量 | 0 | ||
14 | 弹出2 | 3,2 | 计算2-2之间雨量 | 1 | ||
15 | 弹出2 | 3, | 计算3-2之间雨量 | 0 | ||
16 | 弹出3 | |||||
17 | ||||||
合计 | 6 |
具体代码为
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
def calculateRainFall(m,n,h):
res = 0
for i in range(m+1,n):
res+= h-height[i]
return res
def top(s):
return s[-1] if len(s)>0 else (999999,0)
stack =[]
rainFall = 0
for idx, e in enumerate(height):
if len(stack)==0 or top(stack)<e:
stack.append((e,idx))
else:
while(top(stack)[0]<e):
hi,sn = stack.pop()
if len(stack)==0 and (idx-sn>1): #如果遇到栈顶
# here 计算入栈雨量
rainFall+=calculateRainFall(sn,idx,hi)
stack.append((e,idx))
# 2. 开始弹栈
hit,snt = 0,0
while (len(stack)>1):
hi,sn = stack.pop()
hit,snt =top(stack)
# 计算出栈雨量
if (sn-snt>1):
rainFall += calculateRainFall(snt,sn,hi)
return rainFall
结论复杂度分析
本题当中数字进栈一次出栈一次 ,所以最终的复杂度为O(2N)