Skip to content

Commit f8f5fe8

Browse files
author
weiy
committed
trapping rain water hard
1 parent 6c06ae2 commit f8f5fe8

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

Stack/TrappingRainWater.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"""
2+
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
3+
4+
5+
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
6+
7+
Example:
8+
9+
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
10+
Output: 6
11+
12+
13+
图看链接:
14+
https://leetcode.com/problems/trapping-rain-water/description/
15+
16+
思路:
17+
1. 这里想到用单调栈来做,给的例子基本上是单调递减,然后有一个不符合的就开始处理。
18+
19+
不过随之而来的遇到的第一个不合理的地方:
20+
|
21+
| |
22+
| | | |
23+
-----------
24+
2 1 0 1 3
25+
26+
在 2 1 0 之后,出现了第一个不是单调递增的值,1,然后开始处理,处理之后得到值 1(1-0)。可是用后面的 3 能装更多的水。
27+
28+
2. 对上面问题的修复是片面的:
29+
我的想法是再开始判断单调递增,直到不合理的出现。这样修复后可以处理这一类问题,不过随之而来的又一个新的问题:
30+
31+
32+
| |
33+
| | |
34+
| | | | | |
35+
| | | | | | |
36+
------------------
37+
4 2 1 2 3 2 4
38+
39+
显然用两边的 4 可以装更多的水,但用之前的单调递增+单调递减是不能达到这样的效果的。
40+
41+
3. 基于 2 的再改进。
42+
两次思考问题都过于局限,只看到了眼前的一点。
43+
这次的改进依然基于单调栈,遇到非单调递减的值,不会直接清空已经存储的点,而是全部覆盖记录。
44+
45+
比如
46+
4 2 1 2 当遇到第二个 2 时,会进行 2-1 2-2 的记录,留下 4,因为 4此时是 > 2 的,若是 2 1 4 就没必要保留了。
47+
所以放置一个用于覆盖记录的列表。
48+
49+
result = [0] * length
50+
51+
每次非单调递减后就执行一次 stack[0] - i 与最小值的差覆盖,这样覆盖到最后结果就会是正确的。
52+
53+
例:
54+
4 2 1 2 3 2 4
55+
[0, 0, 0, 0, 0, 0, 0]
56+
0 1 2 3 4 5 6
57+
58+
第一次单调递减打破后:
59+
会执行一次 0 - 3 的判断。
60+
[0, 0, 1, 0, 0, 0, 0]
61+
62+
此时栈中剩余的是记录 4 的下标 0 和 记录第二个2的下标 3。
63+
64+
第二次单调递减打破后:
65+
会执行一次 0 - 4 的判断
66+
[0, 0, 1, 0, 0, 0, 0] -> [0, 1, 2, 1, 0, 0, 0]
67+
68+
此时栈中剩余的是 0 和 4
69+
70+
第三次打破后:
71+
会执行一次 0 - 6 的判断
72+
[0, 1, 2, 1, 0, 0, 0] -> [0, 2, 3, 2, 1, 2, 0]
73+
74+
这样的时间复杂度 最差是 O(n²) 最好是 O(n)。
75+
76+
beat
77+
0%
78+
太慢,待改进。
79+
80+
81+
测试地址:
82+
https://leetcode.com/problems/trapping-rain-water/description/
83+
84+
"""
85+
class Solution(object):
86+
def trap(self, height):
87+
"""
88+
:type height: List[int]
89+
:rtype: int
90+
"""
91+
stack = [0]
92+
93+
i = 1
94+
length = len(height)
95+
result = [0] * length
96+
97+
while i < length:
98+
if height[i] <= height[stack[-1]]:
99+
stack.append(i)
100+
i += 1
101+
else:
102+
mins = min(height[stack[0]], height[i])
103+
index = 0
104+
for j in xrange(stack[0], i):
105+
_ = mins - height[j]
106+
107+
if _ > 0 and _ > result[j]:
108+
result[j] = _
109+
110+
if height[stack[0]] <= height[i]:
111+
stack = []
112+
else:
113+
stack = [stack[0]]
114+
115+
stack.append(i)
116+
i += 1
117+
118+
return sum(result)
119+

0 commit comments

Comments
 (0)