美文网首页
截留雨水

截留雨水

作者: 静水流深ylyang | 来源:发表于2018-12-22 22:27 被阅读0次

    版权声明:本文为博主原创文章,转载请注明出处。
    个人博客地址:https://yangyuanlin.club
    欢迎来踩~~~~


    题目描述

    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], return6.

    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!

    题目大意

    给定n个非负整数,表示每根杆的宽度为1的高程图,计算雨后它能收集多少水。
    例如:给定[0,1,0,2,1,0,1,3,2,1,2,1],返回6。
    上述高程图由数组[0,1,0,2,1,0,1,3,2,1,2,1]表示。在这种情况下,有6个单位的雨水(蓝色部分)被困住了。

    思路

    两种思路。
    第一种:
    两次遍历,空间复杂度为O(1),时间复杂度为O(2n)。
    先进行一次遍历,找到数组中的最大值(不是最大值的下标)maxhigh,然后分别进行从两边到maxhigh这个值的位置的遍历,以左边为例,因为已经找到了最大值,从左边第一个值记为left开始向右边进行遍历,当右边的值比左边的值小时,说明形成高度差,该高度差可以截留雨水,如果left右边的值A[i]大于left,就更新left值,将A[i]记为left。
    第二种:
    只需遍历一遍的解决方案,空间复杂度O(1),时间复杂度为O(n)。
    从数组两边向中间找,两边维护两个最大值,每次选较小的那个最大值,然后进行比较,看是否可以截留住雨水。
    具体代码如下所示。
    代码解析代码解析

    代码

    #include<iostream>
    using namespace std;
    
    int trap(int A[], int n)
    {
        if(n <= 2)return 0;
        int left_max = A[0];
        int right_max = A[n-1];
        int i = 1, j = n-2;
        int sum = 0;
        while(i <= j)
        {
            if(left_max <= right_max)
            {
                sum += max(0, left_max-A[i]);
                left_max = max(left_max, A[i]);
                i++;
            }
            else
            {
                sum += max(0, right_max-A[j]);
                right_max = max(right_max, A[j]);
                j--;
            }
        }
        return sum;
    }
    
    int main()
    {
        int A[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
        cout << trap(A, 12) << endl;
        return 0;
    }
    

    代码解析

    首先选择A[0]和A[n-1]作为两边的最大值分别为:left_max和right_max,
    然后从下标为1和n-2的位置分别记为A[ i ]和A[ j ]向中间进行遍历,
    每次选择左右较小的那个max值(因为这样的话可以保证如果存在高度差则一定可以截留住雨水),
    例如,如果left_max比较小,那么就与A[j],进行比较,
    如果left_max - A[j]的值为正数,就说明可以截留住雨水,
    如果left_max - A[j]的值为负数,说明不能截留住雨水,并且当前left_max值已经不是最大值,就更新left_max = A[j]。

    运行结果

    • 以上。

    版权声明:本文为博主原创文章,转载请注明出处。
    个人博客地址:https://yangyuanlin.club
    欢迎来踩~~~~


    相关文章

      网友评论

          本文标题:截留雨水

          本文链接:https://www.haomeiwen.com/subject/icuwkqtx.html