给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
public int trap(int[] height) {
int st = 0;
int all = 0;
if(height.length==0||height.length==1||height.length==2){
return 0;
}
//从第一个连续最大高度开始
while(height[st]<=height[st+1]){
st++;
if(st==height.length-1){
return 0;
}
}
//
for(int i=st;i<height.length-1;){
//定义第一个指针
int j=i+1;
//有连续的两个高度的柱子,选后者,后移
if(height[j]>=height[i]){
i=j;
continue;
}
//定义第二个指针
int k=j+1;
int dis=99999;
int curhigh=j;
boolean ishavahigher = false;
while(k<=height.length-1){
//后面有更高的柱子
if(height[k]>=height[i]){
ishavahigher = true;
curhigh = k;
while(j<k){
all += height[i] - height[j];
j++;
}
i = k;
break;
}else{
//后面没有更高的,找次高相等的当中第一个次高的
int curdis = height[i] - height[k];
if(curdis<dis){
curhigh = k;
dis = curdis;
}
}
k++;
}
//记录下当前后一位置的柱子
int a=j;
//如果没有更高的且次高的位置比j位置高,再算体积
if(!ishavahigher && height[curhigh]>height[j]){
while(j<curhigh){
all += height[curhigh] - height[j];
j++;
}
i = curhigh;
}else if(!ishavahigher && height[curhigh]<=height[a]){
//如果没有更高的且次高的柱子比第二个柱子更矮,是装不下水的,所以后移
i++;
}
// boolean ishavemorethan = false;
// while(height[j]<height[i] && j<height.length-1){
// curall += height[i] - height[j];
// j++;
// if(height[j]>=height[i]){
// ishavemorethan = true;
// break;
// }
// }
// if(ishavemorethan){
// all += curall;
// i = j;
// }else{
// i++;
// }
}
return all;
}