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

相关推荐
码爸5 小时前
线性回归算法
算法·机器学习·线性回归
Coder-magician6 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil2086 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b6 小时前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
青少儿编程课堂7 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
不会就选b7 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展
没有钱的钱仔8 小时前
协方差矩阵含义
算法·机器学习·矩阵
垆边人似月.9 小时前
华为机试题 :和为 K 的子数组个数
算法·leetcode·华为
三*一9 小时前
优化修整算法
前端·javascript·算法