Leetcode[42] Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

Two Pointer

复杂度
O(N), O(1);

思路
因为蓄水多少取决于比较短的那块板的长度。所以每次当左指针指向的板比较短的时候,就将其设置为一个bound,每次向右移动,观察是否有比左边这个bound小的板子的存在,如果有,说明到这个位置可以蓄水。

代码

public int trap(int[] height) {
    int res = 0;
    int left = 0, right = height.length - 1;
    while(left < right) {
        if(height[left] < height[right]) {
            int bound = height[left];
            int i = left + 1;
            while(i < right && height[i] < bound) {
                res += bound - height[i];
                i ++;
            }
            left = i;
        }
        else {
            int bound = height[right];
            int i = right - 1;
            while(i > left && height[i] < bound) {
                res += bound - height[i];
                i --;
            }
            right - i;
        }
    }
    return res;
}

Stack

复杂度
O(N), O(N)

思路
考虑说明时候需要计算蓄水量:
当val > stack.peek()的时候,需要计算能储存的水的多少。每次还需要取出一个mid作为中间值。
如果val < stack.peek(),则一直向stack里面压进去值,不需要直接计算。

代码

public int trap(int[] height) {
    int res = 0;
    Stack<Integer> stack = new Stack<>();
    for(int i = 0; i < height.length; i ++) {
        if(!stack.isEmpty() && height[i] > height[stack.peek()]) {
            while(!stack.isEmpty() && height[i] > height[stack.peek()]) {
                int mid = stack.pop();
                if(!stack.isEmpty()) {
                    res += (Math.min(height[stack.peek()], height[i]) - height[mid]) * (i - stack.peek() - 1);
                }
            }
        }
        stack.push(i);
    }
    return res;
}

hellolittleJ17
10 声望11 粉丝