【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 };

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2017-02-07 09:27  会咬人的兔子  阅读(113)  评论(0编辑  收藏  举报