给定 n 个非负整数表示每个宽度为 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[]数组)
然后再假定右方有无限高墙体存在,然后求出一个阶梯像左的图(left[]数组)
将两图相重叠取交集(min(left[],right[]),我们就可以得到上面我们需要的黑蓝图
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)