思路一:暴力破解
首先我们要找一个最高的柱子,将整个柱子堆划分为2部分,即左部分和右部分,我们分别来统计左右部分可以装的总水量,
以左部分为例:我们从左部分开头开始,向右遍历至中间最高处,
情况1.我们所走的当前位置如果前面有比它高的,那就用
前面最高的高度-当前高度 所得的结果就是这个格子能装的水的高度
情况2.如果所走的位置比前面最高的还高,那就将最高的记做当前的柱子,再走下一个
有部分:和左部分一样,只不过从右向左走。遇到的情况还是一样
/*
* 先找出最高的柱子,左边从左往右,如果该柱子低于前面最高的
* 则存水量为前面最高的减去这个柱子,右边总右向左走
*/
public int trap(int[] height) {
int begin=0,end=height.length-1;
int max=0,maxval=0;
//找到最大值和最大值得下标
for(int i=0;i<height.length;i++) {
if(height[i]>maxval) {
max=i;maxval=height[i];
}
}
int sum=0;
int flag=0;//前面最高的柱子
//从左往右找
for(int i=0;i<max;i++) {
if(height[i]<flag) {//如果这个柱子小于前面最高的
sum=sum+(flag-height[i]);
}
if(height[i]>=flag)//如果大于等于最高的
flag=height[i];
}
flag=0;
for(int i=height.length-1;i>max;i--) {
if(height[i]<flag)//如果这个柱子小于前面最高的
sum=sum+(flag-height[i]);
if(height[i]>=flag)//如果大于等于最高的
flag=height[i];
}
return sum;
}
思路二:使用栈
参考:https://www.jianshu.com/p/024d2e3c13e8
类似于括号匹配问题,先找上升趋势,将其入栈,直到找到下降的,那么这个下降的柱和上升的柱之间一定存在一个坑,我们就要计算这个坑,然后进一步扩大,计算中间的坑,最后将所有的坑加起来,就是所有的总和。
具体的讲解在上面的博客中讲了。
下面是具体的代码
//利用堆栈的方法
public int trap2(int[] height) {
//用来存储height的下标
Stack<Integer> stack=new Stack<>();
int sum=0;
//遍历数组
for(int i=0;i<height.length;i++) {
//如果数组为空或者数组是递减顺序
if(stack.isEmpty()||height[i]<height[stack.peek()]) {
stack.push(i);//此处记录的是数组的下标
}else{//当数组不为递减顺序时,就需要弹栈了
while(!stack.isEmpty()&&height[i]>height[stack.peek()]) {
int pre=stack.pop();//弹出栈顶元素
if(!stack.isEmpty()) {//因为此处要使用栈前面的元素
sum+=(min(height[i],height[stack.peek()])-height[pre])*(i-stack.peek()-1);
}
}
stack.push(i);
}
}
return sum;
}
private int min(int a,int b) {
return a<b?a:b;
}