接雨水--leetcode42

接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

leetCode42接雨水

左右一高一低。
栈为单调递减 没有溢出
遇到增的时候 — pop 至栈为 单调递减—
溢出部分 = 木桶的最低值(一高一低) * (宽度) i当前位置-pop溢出位置 -1 之间的位置
木桶的最低值 = Math.max 当前位置 和溢出位置。

单调栈

    public int trap(int[] height) {
        //是
        int ans = 0;
        Deque<Integer> stack = new LinkedList<Integer>();
        int n = height.length;
        for (int i = 0; i < n; ++i) {
            // 只有左右 高 中间低才能有 木桶
            // height[i]>height[stack.peek()] ***右高**  stack 为单调递减
            while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
                // pop出 left值, 直到为左边界
                int top = stack.pop();
                if (stack.isEmpty()) {
                    break;
                }
                int left = stack.peek();
                // 宽度 = 当前 - left -1; // left 和 cur 之间的距离增加
                int currWidth = i - left - 1;
                // 缺失高度 = 木桶的最小值(当前 和 栈上的高度)- pop的比较小的高度
                // ****i>top***  left>top???? 显然, 不弹出 stack里面 是一个降序的
                int currHeight = Math.min(height[left], height[i]) - height[top];
                ans += currWidth * currHeight;
            }
            // 新增一个
            stack.push(i);
        }
        return ans;

    }

动态规划

每一个位置 缺失高度 = (–>left)左右(<–)到当前最大高度中 木桶最小值

        public int trap(int[] height) {
        // 动态规划
        //  每一个柱子的缺失高度 = (leftMax,rightMax)木桶最小值 - 当前柱子高度
            int n = height.length;
            if (n == 0) {
                return 0;
            }

            int[] leftMax = new int[n];
            leftMax[0] = height[0];
            for (int i = 1; i < n; ++i) {
                leftMax[i] = Math.max(leftMax[i - 1], height[i]);
            }

            int[] rightMax = new int[n];
            rightMax[n - 1] = height[n - 1];
            for (int i = n - 2; i >= 0; --i) {
                rightMax[i] = Math.max(rightMax[i + 1], height[i]);
            }

            int ans = 0;
            for (int i = 0; i < n; ++i) {
                ans += Math.min(leftMax[i], rightMax[i]) - height[i];
            }
            return ans;
        }

双指针

左边界,右边界 leftMax从左(–>)的左边界,rightMax右边界
溢出值= Math.min(rightMax,leftMax) - 当前高度
h[left] < h[right] Math.min = leftMax 左指针++
h[left] > h[right] Math.min = rightMax 右指针–

溢出总高度

    public int trap(int[] height) {
        int ans = 0;
        int left=0,right=height.length-1;
        int leftMax =0,rightMax =0;
        while (left<right){
            // 当前值为最高值 - ans 为0. 达到最高峰的时候,没有溢出.
            // 当前值不为最高值  ans 减去较小的木桶 ans+= (minMax- height[cur])
            leftMax=Math.max(leftMax,height[left]);
            rightMax=Math.max(rightMax,height[right]);
            if (height[left]<height[right]){
                //  木桶较小值 为左边. ans + 溢出部分 左边区域最值leftMax - 当前高度
                ans += leftMax -height[left];
                left++;
            }else {
                ans += rightMax -height[right];
                right--;
            }
        }

        return ans;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值