题目:
利用一个单调栈,一旦触发弹栈就能放雨水。但是要注意边界问题。
宽度如和计算。雨水的高度如和计算。
代码示例:
java
/**
* <h3>接雨水 - 单调栈</h3>
*/
public class TrappingRainWaterLeetcode42 {
public static void main(String[] args) {
System.out.println(trap(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1})); // 6
//System.out.println(trap2(new int[]{4, 2, 9, 3, 2, 5})); // 9
}
static int trap(int[] heights){
LinkedList<Data> stack = new LinkedList<>();
int sums = 0;
for (int i = 0; i < heights.length; i++) {
Data rights = new Data(heights[i], i);//右边界
//要保证栈不为空。为了单调性,栈顶的高度比 右边界的小。才入栈
while(!stack.isEmpty() && stack.peek().height < rights.height){
Data pop = stack.pop();//弹出的
Data left = stack.peek();//现在的栈顶
if(left != null){//不是最左边界才能放
//只要触发弹栈。就标明有位置放雨水
//宽度计算,right 的索引减去 left 的索引-1。比如:3,1.3-1=2-1=1宽度是 1
int width = rights.i - left.i - 1;
//高度计算
int height = Math.min(left.height, rights.height) - pop.height;
sums += width * height;
}
}
stack.push(rights);
}
return sums;
}
static class Data{
int height;
int i; // 索引
public Data(int height, int i) {
this.height = height;
this.i = i;
}
@Override
public String toString() {
return String.valueOf(height);
}
}
}