截留雨水

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

题目描述

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
欢迎来踩~~~~


猜你喜欢

转载自blog.csdn.net/w7239/article/details/85223268