• 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

    来源: 





  • 相关阅读:
    Windows下vim的块选择
    Understand Your Code
    ubuntu中安装man手册查看函数原型
    PypeR
    【入门】用Linux中man命令查询C函数
    用man来查找c函数库 追寻前人的脚步 博客园
    Linux教程 正文 关于vim的模式操作基本概念
    vim的配置管理和部署
    可爱的 Python: 自然语言工具包入门
    简明 Vim 练级攻略
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/1500af07ede3bc9b59c7a22bbf616726.html
Copyright © 2020-2023  润新知