42. Trapping Rain Water

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.

分析

算法一

遍历一遍,找到最高点,然后在左半边遍历,计算每个位置能够达到的最高值,如果当前高度<左边最高值,则容积为
maxleft - height[i]
否则更新maxleft
右边同理

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
    int trap(vector<int>& height) {
        if(height.empty())return 0;
        int maxi = 0, maxh = height[0];
        int volume = 0;
        for(int i = 0; i < height.size(); ++i){
            if(height[i] > height[maxi]) maxi = i;
        }
        int maxil = 0;
        for(int i = 1; i < maxi; ++i){
            if(height[i] < height[maxil]){
                volume += height[maxil] - height[i];
            }
            else{
                maxil = i;
            }
        }
        int maxir = height.size() - 1;
        for(int j = height.size() - 1; j > maxi; j--){
            if(height[j] < height[maxir])
                volume += height[maxir] - height[j];
            else
                maxir = j;
        }
        return volume;
    }
};

算法二

Two Pointers,双指针法
左右双指针,每边各一个max值,maxleft 和 maxright,想象成水桶的长短边。左右双指针在内移时候随时更新maxleft 和 maxright。 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
    int trap(vector<int>& A) {
        int left=0; 
        int n = A.size();
        int right=n-1; 
        int res=0;
        int maxleft=0, maxright=0;
        while(left<=right){
            if(A[left]<=A[right]){
                if(A[left]>=maxleft) maxleft=A[left];
                else res+=maxleft-A[left];
                left++;
            }
            else{
                if(A[right]>=maxright) maxright= A[right];
                else res+=maxright-A[right];
                right--;
            }
        }
        return res;
    }
};

算法过程如下:
初始化:
1
2
3
4
5
6
L             R         0
|     |            maxL 0
|     |       |    maxR 0
| |   | |   | |    res  0
| | | | | | | |
0 1 2 3 4 5 6 7
执行 1 次后,执行前:A[left:0] > A[right:7]
1
2
3
4
5
6
L           R           0 1
|     |            maxL 0 0
|     |       |    maxR 0 3
| |   | |   | |    res  0 0
| | | | | | | |
0 1 2 3 4 5 6 7

执行 2 次后,执行前:A[left:0] > A[right:6]
1
2
3
4
5
6
L         R             0 1 2
|     |            maxL 0 0 0
|     |     * |    maxR 0 3 3
| |   | |   | |    res  0 0 1
| | | | | | | |
0 1 2 3 4 5 6 7

执行 3 次后,执行前:A[left:0] > A[right:5]
1
2
3
4
5
6
L       R               0 1 2 3
|     |            maxL 0 0 0 0
|     |   * * |    maxR 0 3 3 3
| |   | | * | |    res  0 0 1 3
| | | | | | | |
0 1 2 3 4 5 6 7

执行 4 次后,执行前:A[left:0] > A[right:4]
1
2
3
4
5
6
L     R                 0 1 2 3 4
|     |            maxL 0 0 0 0 0
|     | * * * |    maxR 0 3 3 3 3
| |   | | * | |    res  0 0 1 3 4
| | | | | | | |
0 1 2 3 4 5 6 7

执行 5 次后,执行前:A[left:0] <= A[right:3]
1
2
3
4
5
6
  L   R                 0 1 2 3 4 5
|     |            maxL 0 0 0 0 0 4
|     | * * * |    maxR 0 3 3 3 3 3
| |   | | * | |    res  0 0 1 3 4 4
| | | | | | | |
0 1 2 3 4 5 6 7

执行 6 次后,执行前:A[left:1] <= A[right:3]
1
2
3
4
5
6
    L R                 0 1 2 3 4 5 6
| *   |            maxL 0 0 0 0 0 4 4
| *   | * * * |    maxR 0 3 3 3 3 3 3
| |   | | * | |    res  0 0 1 3 4 4 6
| | | | | | | |
0 1 2 3 4 5 6 7

执行 7 次后,执行前:A[left:2] <= A[right:3]
1
2
3
4
5
6
      LR                0 1 2 3 4 5 6 7
| * * |            maxL 0 0 0 0 0 4 4 4
| * * | * * * |    maxR 0 3 3 3 3 3 3 3
| | * | | * | |    res  0 0 1 3 4 4 6 9
| | | | | | | |
0 1 2 3 4 5 6 7

来源: 





posted @ 2016-11-30 14:34  copperface  阅读(257)  评论(0编辑  收藏  举报