【LeetCode每日一题】 单调栈的案例 42. 接雨水

这道题是困难,但是可以使用单调栈,非常简洁通俗。

关于单调栈可以参考单调栈总结以及Leetcode案例解读与复盘

42. 接雨水

给定 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

思路:首先理解题意

我们需要接雨水,所以必然是会要形成一个凹槽,因此我们只要构建一个单调递减栈,(凹槽的左边),当遇到大于栈顶元素的元素时,说明可以开始计算接的雨水的面积。直接通过下图理解更好理解。


这里有几个需要注意的:

  • 首先,和坐标轴是没有办法接雨水的
  • 在找凹槽的左边界时,需要先将栈顶元素弹出,因此做完一次计算的操作后,left变成了栈顶元素,原先的栈顶元素已经被弹出
  • 因为将栈底元素已经弹出了,因此我们在计算面积的时候也不会重复,具体看上图面积黄色色块。

代码实现

js 复制代码
var trap = function (height) {
    // 遍历,构造单调递减的单调栈,一旦遇到递增,就开始加
    let stack = [];
    let ans = 0;
    for(let i = 0; i < height.length; i++){
        while(stack.length && height[i] > height[stack.at(-1)]){
            // 可能出现凹地,寻找left
            let peek = stack.pop();
            let left = stack.length ? stack.at(-1) : -1;

            if(left !== -1){
                let width = i - left - 1;
                let h = Math.min(height[left], height[i]) - height[peek];
                ans += width * h;
            }
        }
        stack.push(i);
    }
    return ans;
}
console.log(trap([0,4,2,0,3,2,5]))

类似习题:
【LeetCode每日一题】 单调栈的案例84 柱状图中最大的矩形

相关推荐
!停6 分钟前
数据结构空间复杂度
java·c语言·算法
一路往蓝-Anbo6 分钟前
第 4 篇:策略模式 (Strategy) —— 算法的热插拔艺术
网络·驱动开发·stm32·嵌入式硬件·算法·系统架构·策略模式
不染尘.9 分钟前
二分算法(优化)
开发语言·c++·算法
不吃橘子的橘猫10 分钟前
Verilog HDL基础(概念+模块)
开发语言·学习·算法·fpga开发·verilog
苦藤新鸡13 分钟前
49.二叉树的最大路径和
数据结构·算法·深度优先
源代码•宸15 分钟前
Leetcode—144. 二叉树的前序遍历【简单】
经验分享·算法·leetcode·面试·职场和发展·golang·dfs
m0_7369191020 分钟前
C++中的观察者模式
开发语言·c++·算法
Anastasiozzzz21 分钟前
LeetCodeHot100 347. 前 K 个高频元素
java·算法·面试·职场和发展
fantasy_arch23 分钟前
SVT-AV1编码 递归子块划分
算法·av1
jay神27 分钟前
基于深度学习和协同过滤算法的美妆商品推荐系统
人工智能·深度学习·算法·毕业设计·协同过滤算法