【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 柱状图中最大的矩形

相关推荐
董董灿是个攻城狮4 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki4 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
qqxhb6 小时前
零基础数据结构与算法——第四章:基础算法-排序(上)
java·数据结构·算法·冒泡·插入·选择
FirstFrost --sy7 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
森焱森8 小时前
垂起固定翼无人机介绍
c语言·单片机·算法·架构·无人机
搂鱼1145148 小时前
(倍增)洛谷 P1613 跑路/P4155 国旗计划
算法
Yingye Zhu(HPXXZYY)8 小时前
Codeforces 2021 C Those Who Are With Us
数据结构·c++·算法
无聊的小坏坏9 小时前
三种方法详解最长回文子串问题
c++·算法·回文串
长路 ㅤ   9 小时前
Java后端技术博客汇总文档
分布式·算法·技术分享·编程学习·java后端
秋说10 小时前
【PTA数据结构 | C语言版】两枚硬币
c语言·数据结构·算法