【22】42. Trapping Rain Water
42. Trapping Rain Water (cf.container with most water)
- Total Accepted: 98539
- Total Submissions: 277383
- Difficulty: Hard
- Contributors: Admin
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.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
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!
Solution 1:
1 class Solution { 2 public: 3 int trap(vector<int>& height) { 4 int n = height.size(); 5 if(n < 2) return 0; 6 7 vector<int> maxL(n, 0), maxR(n, 0);//问题出现在这里 vector要初始化 或者用pushback加值 8 9 int max = height[0]; 10 //从左往右扫,记录每一个index的左边最高是多少 11 12 maxL[0] = 0; 13 //for(int i = 0; i < n; i++){ 14 for(int i = 1; i < n - 1; i++){ 15 maxL[i] = max; 16 if(max < height[i]){ 17 max = height[i]; 18 } 19 } 20 //从右往左扫,记录每一个index的右边的最高是多少 21 //从右往左扫,记录最大圈水数 22 max = height[n - 1]; 23 int trap = 0; 24 int traps = 0; 25 26 maxR[n - 1] = 0; 27 //for(int i = n - 1; i >= 0; i--){ 28 for(int i = n - 2; i > 0; i--){ 29 maxR[i] = max; 30 trap = min(maxL[i], maxR[i]) - height[i]; 31 if(trap > 0){ 32 traps += trap; 33 } 34 if(max < height[i]){ 35 max = height[i]; 36 } 37 } 38 return traps; 39 } 40 };
Solution 2:两边向中间扫(left,right)
只需遍历一次。left, right指针分别指向头尾。如果left对应的height值小于right,则向右扫;反之向左。如果当前值小于left与right比较的较小值,则把差值存入结果。
1 class Solution { 2 public: 3 int trap(vector<int>& height) { 4 int res = 0; 5 int left = 0; 6 int right = height.size() - 1; 7 while(left < right){ 8 int mn = min(height[left], height[right]); 9 if(mn == height[left]){ 10 left++; 11 while(height[left] < mn && left < right){ 12 res += mn - height[left++];//别忘了++ 13 } 14 }else{ 15 right --; 16 while(left < right && height[right] < mn){ 17 res += mn - height[right--];// 18 } 19 } 20 } 21 return res; 22 } 23 };