【学习笔记】【力扣题库】接雨水 难度:困难

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
【学习笔记】【力扣题库】接雨水 难度:困难_第1张图片

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

解题逻辑:

1、总逻辑:我们只要由给出的数据所构成的黑色图 求出包括了水部分的黑蓝色图,再由黑蓝色图减去黑色图数据,就可以得到水的数量

2、求黑蓝图:求黑蓝图时,我们可以假定左方有无限高墙体存在,然后求出一个阶梯向右的图(right[]数组)

【学习笔记】【力扣题库】接雨水 难度:困难_第2张图片

然后再假定右方有无限高墙体存在,然后求出一个阶梯像左的图(left[]数组)

【学习笔记】【力扣题库】接雨水 难度:困难_第3张图片

将两图相重叠取交集(min(left[],right[]),我们就可以得到上面我们需要的黑蓝图

【学习笔记】【力扣题库】接雨水 难度:困难_第4张图片【学习笔记】【力扣题库】接雨水 难度:困难_第5张图片

3、如何求出带有左右墙的图(left[],right[])

left[]:(右边有墙)

从左往右看,只要当前位置没上一个位置高,那么就让当前位置的高度等于上一个位置的高度

right[]:(左边有墙)

从右往左看,只要当前位置没上一个位置高,那么就让当前位置的高度等于上一个位置的高度

最后就是显而易见的,用这个黑蓝图-黑图,就得到水的数量

放上代码实现:

class Solution {
    public int trap(int[] height) {

        int length = height.length;
        if(length==0)return 0;

        int[] left = new int[length];
        int[] right = new int[length];

        left[0] = height[0];
        right[length-1] = height[length-1];

        for(int i = 1;i < length;i++){//制造左墙图与右墙图
            left[i] = Math.max(left[i-1],height[i]);
            right[length-i-1] = Math.max(right[length-i],height[length-i-1]);
        }

        int water = 0;

        for(int i = 0;i < length;i++){//两图的最小值就相当于对两图求交集,再减去输入的数据,就可以得到水的数量了
            water+= Math.min(left[i],right[i]) - height[i];
        }

        return water;
    }
}

时间复杂度O(n)

你可能感兴趣的:(算法)