|
| 1 | +## Trapping Rain Water |
| 2 | +https://leetcode.com/problems/trapping-rain-water/description/ |
| 3 | + |
| 4 | +## Problem Description |
| 5 | +> 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. |
| 6 | +
|
| 7 | + |
| 8 | + |
| 9 | +> 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! |
| 10 | +
|
| 11 | +``` |
| 12 | +Input: [0,1,0,2,1,0,1,3,2,1,2,1] |
| 13 | +Output: 6 |
| 14 | +``` |
| 15 | + |
| 16 | +## Solution |
| 17 | + |
| 18 | +The difficulty of this problem is `hard`. |
| 19 | +We'd like to compute how much water a given elevation map can trap. |
| 20 | + |
| 21 | +A brute force solution would be adding up the maximum level of water that each element of the map can trap. |
| 22 | + |
| 23 | +Pseudo Code: |
| 24 | +```js |
| 25 | +for(let i = 0; i < height.length; i++) { |
| 26 | + area += h[i] - height[i]; // the maximum level of water that the element i can trap |
| 27 | +} |
| 28 | +``` |
| 29 | + |
| 30 | +Now the problem becomes how to calculating h[i], which is in fact the minimum of maximum height of bars on both sides minus height[i]: |
| 31 | +`h[i] = Math.min(leftMax, rightMax)` where `leftMax = Math.max(leftMax[i-1], height[i])` and `rightMax = Math.max(rightMax[i+1], height[i])`. |
| 32 | + |
| 33 | +For the given example, h would be [0, 1, 1, 2, 2, 2 ,2, 3, 2, 2, 2, 1]. |
| 34 | + |
| 35 | +The key is to calculate `leftMax` and `rightMax`. |
| 36 | + |
| 37 | +## Key Points |
| 38 | + |
| 39 | +- Figure out the modeling of `h[i] = Math.min(leftMax, rightMax)` |
| 40 | + |
| 41 | +## Code (JavaScript/Python3/C++) |
| 42 | + |
| 43 | +JavaScript Code: |
| 44 | + |
| 45 | +```js |
| 46 | + |
| 47 | +/* |
| 48 | + * @lc app=leetcode id=42 lang=javascript |
| 49 | + * |
| 50 | + * [42] Trapping Rain Water |
| 51 | + * |
| 52 | + */ |
| 53 | +/** |
| 54 | + * @param {number[]} height |
| 55 | + * @return {number} |
| 56 | + */ |
| 57 | +var trap = function(height) { |
| 58 | + let max = 0; |
| 59 | + let volumn = 0; |
| 60 | + const leftMax = []; |
| 61 | + const rightMax = []; |
| 62 | + |
| 63 | + for(let i = 0; i < height.length; i++) { |
| 64 | + leftMax[i] = max = Math.max(height[i], max); |
| 65 | + } |
| 66 | + |
| 67 | + max = 0; |
| 68 | + |
| 69 | + for(let i = height.length - 1; i >= 0; i--) { |
| 70 | + rightMax[i] = max = Math.max(height[i], max); |
| 71 | + } |
| 72 | + |
| 73 | + for(let i = 0; i < height.length; i++) { |
| 74 | + volumn = volumn + Math.min(leftMax[i], rightMax[i]) - height[i] |
| 75 | + } |
| 76 | + |
| 77 | + return volumn; |
| 78 | +}; |
| 79 | + |
| 80 | +``` |
| 81 | + |
| 82 | +Python Code: |
| 83 | + |
| 84 | +```python |
| 85 | +class Solution: |
| 86 | + def trap(self, heights: List[int]) -> int: |
| 87 | + n = len(heights) |
| 88 | + l, r = [0] * (n + 1), [0] * (n + 1) |
| 89 | + ans = 0 |
| 90 | + for i in range(1, len(heights) + 1): |
| 91 | + l[i] = max(l[i - 1], heights[i - 1]) |
| 92 | + for i in range(len(heights) - 1, 0, -1): |
| 93 | + r[i] = max(r[i + 1], heights[i]) |
| 94 | + for i in range(len(heights)): |
| 95 | + ans += max(0, min(l[i + 1], r[i]) - heights[i]) |
| 96 | + return ans |
| 97 | +``` |
| 98 | + |
| 99 | +C++ code: |
| 100 | + |
| 101 | +```c++ |
| 102 | +class Solution { |
| 103 | +public: |
| 104 | + int trap(vector<int>& height) { |
| 105 | + //check for empty input array |
| 106 | + if(height.empty()) |
| 107 | + return 0; |
| 108 | + int size = height.size(); |
| 109 | + int leftMax[size], rightMax[size]; |
| 110 | + //initialization |
| 111 | + leftMax[0] = height[0]; |
| 112 | + rightMax[size - 1] = height[size - 1]; |
| 113 | + //find leftMax for each element i |
| 114 | + for(int i = 1; i < size; ++i) |
| 115 | + leftMax[i] = max(leftMax[i-1], height[i]); |
| 116 | + //find rightMax for each element i |
| 117 | + for(int i = size - 2; i >= 0; --i) |
| 118 | + rightMax[i] = max(rightMax[i+1], height[i]); |
| 119 | + //caculating the result |
| 120 | + int ans = 0; |
| 121 | + for(int i = 0; i < size; ++i) |
| 122 | + ans += min(leftMax[i], rightMax[i]) - height[i]; |
| 123 | + return ans; |
| 124 | + } |
| 125 | +}; |
| 126 | +``` |
| 127 | +
|
| 128 | +## Similar Problems |
| 129 | +
|
| 130 | +- [84.largest-rectangle-in-histogram](https://github.com/azl397985856/leetcode/blob/master/problems/84.largest-rectangle-in-histogram.md) |
0 commit comments