Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Example 1:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) 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.
Example 2:
Input: height = [4,2,0,3,2,5]
Output: 9
Constraints:
n == height.length
1 <= n <= 2 * 10^4
0 <= height[i] <= 10^5
Ref: https://leetcode.com/problems/trapping-rain-water/solutions/1374608/c-java-python-maxleft-maxright-so-far-with-picture-o-1-space-clean-concise/
A ith
bar can trap water if and only if there exist a higher bar to the left and a higher bar to the right of ith
bar.
And the water it trapped is: min(max_left[i], max_right[i]) - each_height
So in order to get o ( n ) o(n) o(n) time complexity, first we generate max_left
and max_right
.
Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)
Use 2 pointers to calculate max_left
and max_right
as we go.
How to decide to move left
or right
? If max_left < max_right
, that means trapped water is decided by max_left
, so we move left
.
Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( 1 ) o(1) o(1)
class Solution:
def trap(self, height: List[int]) -> int:
max_left, max_right = [0] * len(height), [0] * len(height)
x = 0
for i in range(len(height) - 1):
if height[i] > x:
x = height[i]
max_left[i + 1] = x
x = 0
for i in range(len(height) - 1, 0, -1):
if height[i] > x:
x = height[i]
max_right[i - 1] = x
res = 0
for i, each_height in enumerate(height):
res += max(min(max_left[i], max_right[i]) - each_height, 0)
return res
class Solution:
def trap(self, height: List[int]) -> int:
max_left, max_right = height[0], height[-1]
left, right = 1, len(height) - 2
res = 0
while left <= right:
if max_left <= max_right:
if max_left <= height[left]:
max_left = height[left]
else:
res += max_left - height[left]
left += 1
else:
if max_right <= height[right]:
max_right = height[right]
else:
res += max_right - height[right]
right -= 1
return res