单调栈 + 动态规划(42. 接雨水)

动态规划

class Solution {
    public int trap(int[] height) {
        int ans = 0;
        int n = height.length;
        int leftmax[] = new int[n];
        int rightmax[] = new int[n];
        leftmax[0] = height[0];rightmax[n - 1] = height[n - 1];
        for(int i = 1;i < n;i++){
            leftmax[i] = Math.max(leftmax[i - 1],height[i]);
        }
        for(int i = n - 2; i >= 0;i--){
            rightmax[i] = Math.max(rightmax[i + 1],height[i]);
        }
        for(int i = 1;i < n;i++){
            ans += Math.min(leftmax[i],rightmax[i]) - height[i];
        }
        return ans;
    }
}

/*
基本思想:每根柱子积水量由左右柱子最小的决定积水量。所以分别从左从右遍历得到左边最大值,右边最大值。然后再遍历,
左右两边柱子最小值 减去该位置柱子高度即为此位置可积水量。

 */

单调栈

class Solution {
    public int trap(int[] height) {
        Stack st = new Stack<>();
        int ans = 0;
        st.push(0);
        for(int i = 1;i < height.length;i++){
            if(height[i] < height[st.peek()]){
                st.push(i);
            }
            else if(height[i] == height[st.peek()]){
                st.pop();
                st.push(i);
            }
            else{
                while(!st.empty() && height[i] > height[st.peek()]){
                    int low = st.peek();
                    st.pop();
                    if(!st.empty()){
                        int h = Math.min(height[i] - height[low],height[st.peek()] - height[low]); 
                        int w = i - st.peek() - 1;
                        ans += h * w;
                    }
                }
                st.push(i);
            }
        }
        return ans;
    }
}
/*
单调栈
之前写过c++的 计算行高int h=min(height[i],height[st.top()])-height[left];//计算行的高
在c语言情况下可以运行
但是java环境下不可以了 仔细排查后 发现正确的情况下应该是
int h = Math.min(height[i] - height[low],height[st.peek()] - height[low]); 
这样就是先算低的,再算高的,但是你得把高确定好了!!!他这个高要注意了。

本题用单调栈解答 一个是单调栈思想解题  一个是栈的使用,感觉不熟练啊 

 */

你可能感兴趣的:(算法笔记,动态规划,算法)