Question
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
Solution 1 -- DP
The key question is converted into a sum, considering the amount of water each grid can contribute. As shown above, the maximum amount of water that can be stored on each of its left and right sides determined by the grid.
volumn = min(max_left, max_right) - height
So we can be calculated by DP and each grid max_left max_right, and thus the total amount of water can be obtained.
1 class Solution: 2 def trap(self, height: List[int]) -> int: 3 if not height: 4 return 0 5 L = len(height) 6 dp_right = [height[0]] + [0] * (L - 1) 7 dp_left = [0] * (L - 1) + [height[L - 1]] 8 result = 0 9 for i in range(1, L): 10 dp_left[i] = max(dp_left[i - 1], height[i - 1]) 11 for i in range(L - 2, 0, -1): 12 dp_right[i] = max(dp_right[i + 1], height[i + 1]) 13 tmp = min(dp_left[i], dp_right[i]) - height[i] 14 if tmp > 0: 15 result += tmp 16 return result
Solution 2 -- Two Pointers
Double pointer method, a traverse.
1 class Solution: 2 def trap(self, height: List[int]) -> int: 3 if not height: 4 return 0 5 l, r = 0, len(height) - 1 6 result = 0 7 while l < r: 8 tmp = min(height[l], height[r]) 9 if height[l] < height[r]: 10 l += 1 11 while l < r and height[l] < tmp: 12 result += tmp - height[l] 13 l += 1 14 else: 15 r -= 1 16 while l < r and height[r] < tmp: 17 result += tmp - height[r] 18 r -= 1 19 return result