leetcode42. 接雨水(单调栈-java)

265 篇文章 2 订阅
235 篇文章 0 订阅
文章介绍了如何使用单调栈解决LeetCode上的接雨水问题,通过维护栈内元素单调递减,找到每个位置两侧能形成雨水的柱子,从而计算出可接雨水总量。示例代码展示了具体的实现过程。
摘要由CSDN通过智能技术生成

leetcode42. 接雨水

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/trapping-rain-water

题目描述

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

示例1:
在这里插入图片描述
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:
输入:height = [4,2,0,3,2,5]
输出:9

提示:
n == height.length
1 <= n <= 2 * 10000
0 <= height[i] <= 10000

单调栈解题

单调栈其实就是在栈的基础上,维持一个栈内元素单调。
在这道题,由于需要找某个位置两侧比其高的柱子(只有两侧有比当前位置高的柱子,当前位置才能接下雨水),我们可以维持栈内元素的单调递减。
找某侧最近一个比其大的值,使用单调栈维持栈内元素递减;找某侧最近一个比其小的值,使用单调栈维持栈内元素递增 …
当某个位置的元素弹出栈时,例如位置 a ,我们自然可以得到 a 位置两侧比 a 高的柱子:

一个是导致 a 位置元素弹出的柱子( a 右侧比 a 高的柱子)
一个是 a 弹栈后的栈顶元素(a 左侧比 a 高的柱子)

当有了 a 左右两侧比 a 高的柱子后,便可计算 a 位置可接下的雨水量。

我们可以用数组来优化栈结构,这样常数时间效率更高.

代码演示

  /**
     * 接雨水
     * @param height
     * @return
     */
    public int trap(int[] height) {
        if (height == null || height.length < 3){
            return 0;
        }
        int N = height.length;
        int[]stack = new int[N];
        int stackSize = 0;
        int ans = 0;
        for (int i = 0; i < N;i++){
            while (stackSize != 0 && height[i] > height[stack[stackSize - 1]]){
                int cur = stack[--stackSize];
                //stackSize == 0 说明左边没有值,无法接雨水,直接结束当前循环
                if (stackSize == 0){
                    break;
                }
                //左边柱子在的位置
                int l = stack[stackSize - 1];
                //宽度
                int w = i - l - 1;
                //高度
                int h = Math.min(height[l],height[i] ) - height[cur];
                ans += (w * h);
            }
            stack[stackSize++] = i;
        }

        return ans;
    }

单调栈专题

leetcode1856. 子数组最小乘积的最大值

leetcode84. 柱状图中最大的矩形

leetcode.85. 最大矩形

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值