看到这么一个题,觉得挺有意思的,原文链接 http://blog.jobbole.com/50705/
如上图,有不同高度的墙。
这个图片由一个整数数组所代表,数组中每个数是墙的高度。表示为数组[2,7,3,1,5,3]
以1×1的方块为单位计算容积。假如开始下雨了,那么墙之间的水坑能够装多少水呢?
思路:
积水的常识:两边高,中间低才会积水,积水的深度取决于较低的那个边。
方法1: 先找到最高的墙,最左边到最高的墙之间,只要有左墙>右墙的情况,便可和最高强形成积水,最右边同理;
[2,7,3,1,5,3],最大值下标为1;
1的左边,2小于7,显然不能装水,waterLeft=0;
然后从最右边遍历,index=5,max=3;
index=4,a[4]>max ,max=5;
index=3, a[3]<max, waterRight=waterRight+max-a[3]=0+5-1=4;
index=2, a[2]<max,waterRight=waterRight+max-a[2]=4+5-3=6;
此方法遍历次数为2;
方法2:方法1是从中间至两边,该方法是从两边到中间,右墙高于左墙,则以右墙为基准,从左边遍历,如果存在左墙>右墙的情况,则能积水,反之同理;
<span style="white-space:pre"> </span>public static int waterCalculation(int[] wall){
int pLeft=0;
int pRight=wall.length-1;
int maxLeft=wall[pLeft];//左侧最高墙
int maxRight=wall[pRight];//右侧最高墙
int pool=0;//积水
while(pLeft<pRight){
if(maxLeft<maxRight){//如果右侧墙高一些,则以该墙为最高墙,并从左侧寻找左墙>右墙的情况
pLeft=pLeft+1;
if(wall[pLeft]>=maxLeft){//
maxLeft=wall[pLeft];
}else{
pool=pool+maxLeft-wall[pLeft];
}
}else{
pRight=pRight-1;
if(wall[pRight]>=maxRight){//
maxRight=wall[pRight];
}else{
pool=pool+maxRight-wall[pRight];
}
}
}
return pool;
}
<span style="white-space:pre"> </span>public static void main(String[] args){
int[] a={2,7,3,1,5};
System.out.println(Arrays.toString(a)+"的积水为:"+WaterCalculation.waterCalculation(a));
int[] b={2,5,1,2,3,4,7,6};
System.out.println(Arrays.toString(b)+"的积水为:"+WaterCalculation.waterCalculation(b));
int[] c={2,5,1,3,1,2,1,7,7,6};
System.out.println(Arrays.toString(c)+"的积水为:"+WaterCalculation.waterCalculation(c));
}
[2, 7, 3, 1, 5]的积水为:6
[2, 5, 1, 2, 3, 4, 7, 6]的积水为:10
[2, 5, 1, 3, 1, 2, 1, 7, 7, 6]的积水为:17