给定 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
我的思路:两层循环,第一层确定左柱,第二层确定右柱。右柱确定方法为:从左柱位置起始,往右扫描,如果有比左柱大的柱,则选为右柱,如果没有,则选右侧最大值为柱。确定了柱以后,以两柱最小者,与中间柱做差,差值为可盛放的水量,并把中间做过差的柱置为相同高度,防止重复计算。
我的代码:
public class TrappingRainWater {
public int trap(int[] height) {
int res = 0;
if(height.length == 0||height.length == 1)return res;
for(int i = 0;i<height.length-1;i++) {
if(height[i] == 0)continue;
int max = i+1;
int j = i+1;
boolean find = false;
for(;j<height.length;j++) {
//找右边比左边大的为柱
if(height[j]>=height[i]) {
find = true;
break;
}
//如果没找到则用右边最大值为柱
if(height[j]>height[max])max = j;
}
if(find) {
for(int m = i+1;m<j;m++) {
res+=(height[i]-height[m]);
height[m] = height[i];
}
i = j-1;
}else {
//没有比tHeight[i]大,但有一个最大值
for(int m = i+1;m<max;m++) {
res+=(height[max]-height[m]);
height[m] = height[max];
}
i = max-1;
}
}
return res;
}
public static void main(String[] args) {
System.out.println(new TrappingRainWater().trap(new int[] {
0,1,0,2,1,0,1,3,2,1,2,1
}));
System.out.println(new TrappingRainWater().trap(new int[] {
4,2,3
}));
System.out.println(new TrappingRainWater().trap(new int[] {
0,1,0,2,1,0,1,3,2,1,2,1
}));
}
}
运行结果: