Question
在 Leetcode 的 Topic: Array 下做一道题
Answer
'''
LeetCode
Topic: Array
42. Trapping Rain Water: https://leetcode.com/problems/trapping-rain-water
Description:
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.
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!
Example:
Input : [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
'''
class Solution:
'''
type height: List[int]
return type: int
'''
def trap(self, height):
'''
Solution 1:
竖着计算,每一列计算一次。
先从左侧扫描,找到每一列左侧最高的高度。再从右侧扫描,找到右侧最高的高度。
若左侧最高和右侧最高都比此列更高,则较小者减去此列高度即为此列蓄水量。
Time Complexity: O(n)
Space Complexity: O(n)
'''
left_top = [0 for i in range(len(height))] # Initialize
left_max = 0 # Initialize
for i in range(len(height)): # Scan "height"
if height[i] > left_max: # Find the highest left for each element
left_max = height[i]
left_top[i] = left_max
sum = 0 # Initialize
right_max = 0 # Initialize
for i in reversed(range(len(height))): # Same as left
if height[i] > right_max:
right_max = height[i]
if min(right_max, left_top[i]) > height[i]: # Calculate
sum += min(right_max, left_top[i]) - height[i]
return sum
def trap2(self, height):
'''
Solution 2:
用栈,横着计算。
从左往右扫描,若当前列不高于前一列,则将当前列的标号压栈。
当此列高度 A 大于栈顶元素对应高度 B 时,栈顶元素出栈,计算 A 与 B 的距离(即横跨了多少列),再将此距离乘可蓄水高度即可。
重复上述过程直到扫描结束。
Time Complexity: O(n)
Space Complexity: O(n)
'''
stack = []
sum = 0
for i in range(len(height)):
while stack and height[i] > height[stack[-1]]:
top = stack.pop()
if not stack: break
sum += (i - stack[-1] - 1) * (min(height[i], height[stack[-1]]) - height[top])
stack.append(i)
return sum
结果: