题目
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
思路
单调递减栈:当找到一根比前面高的柱子,就可以接雨水,当后面的比前面的低就不可以接。因此相当于寻找右边第一个更大的,那么就是单调递减栈。
雨水的区域:右边的目前遍历到的数字,底部是栈顶,左边是栈顶的前一个。
计算:水坑高度——左右两边更低的元素减去底部。宽度:左右下标差。
如果出栈后栈为空,则不计算面积。将当前入栈,进行下一次循环。
代码
public int trap(int[] height) {
//建立单调递减栈,找右边第一个更大的
int len = height.length;
int sum = 0;
Deque<Integer> stack = new LinkedList<>();
for(int i = 0;i<len;i++){
int cur = height[i];
while(!stack.isEmpty()&&cur>height[stack.peek()]){
int preindex = stack.pop();
//出栈后栈为空就不计算
if(!stack.isEmpty()){
int l = stack.peek();
int r = i;
int h = Math.min(height[l],height[r]);
sum+=(h-height[preindex])*(r-l-1);
}
}
stack.push(i);
}
return sum;
}