思路一:暴力破解
首先我們要找一個最高的柱子,將整個柱子堆劃分爲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;
}