题解 | #接雨水问题#单调栈解法
接雨水问题
http://www.nowcoder.com/practice/31c1aed01b394f0b8b7734de0324e00f
- 这题完全可以用双指针来做,从两端往中间扫描,默认右边大,左边小往中间扫描,左边的小高度减去相应的底就是该位置的盛水量,直到左右指针相遇。
- 这题也可以用单调栈来做。分析:什么时候开始计算雨水:当某一个位置的两端高度大于该高度的时候就可以盛雨水。即找到第一个大于他的就开始计算面积。
- 什么时候正常入栈呢,那就是没有找到大于他的,所以是个单调递减的栈
- 当遇到一个比栈顶大的元素的时候,考虑计算该位置的面积。高度:左右两边的最小高度-盛水的底部高度,宽度:左右两边的矩形差值。注意底部高度只能使用一次,使用完要pop。
public long maxWater (int[] arr) { // write code here Stack<Integer> stack = new Stack<>(); long res =0; for(int i =0 ;i<arr.length;i++){ while(!stack.isEmpty() && arr[i]>arr[stack.peek()]){ int top = stack.pop();//盛水的水底,用过了就要pop出来 if(stack.isEmpty()){//栈中没有元素没有底了 break; } int left = stack.peek(); long len = i -left-1; long heightTemp = Math.min(arr[i],arr[left])-arr[top]; res+=len*heightTemp; } stack.push(i); } return res; }