42. 接雨水

单调栈

解题思路

  1. 声明一个单调递减的栈;

  2. 遍历柱子,维护这个单调栈,并计算凹槽的面积;

  3. 入栈:如果 当前的板子高度 < 栈顶板子高度,则不会形成凹槽,则入栈该板子;

  4. 出栈:如果 当前的板子高度 > 栈顶板子高度,则会形成凹槽;

    • 出栈栈顶板子高度为 top,此时栈顶板子高度为 top‘、索引为 h‘
    • 计算宽度:当前板子索引 - h‘ - 1
    • 计算高度:Math.min(当前板子高度, top‘) - top
    • 面积 = 宽 * 高,根据已知的宽度和高度求出凹槽的面积;

图解

复杂度

  1. 时间复杂度:O(n),其中 n 是数组 height 的长度;从 0n−1 的每个下标最多只会入栈和出栈各一次;

  2. 空间复杂度:O(n),其中 n 是数组 height 的长度;空间复杂度主要取决于栈空间,栈的大小不会超过 n

代码实现

var trap = function (height) {
    // 1. 声明一个单调递减的栈
    let res = 0;
    const stack = [];

    // 2. 遍历柱子,维护这个单调栈
    for (let i = 0; i < height.length; ++i) {
        // 2-1. 如果栈不为空,且栈顶元素<当前柱子的高度,说明可以形成水坑
        while (stack.length && height[i] > height[stack[stack.length - 1]]) {
            const top = stack.pop();
            if (!stack.length) break;

            const left = stack[stack.length - 1];
            const currWidth = i - left - 1;
            const currHeight = Math.min(height[left], height[i]) - height[top];
            res += currWidth * currHeight;
        }
        // 2-2. 放入单调栈
        stack.push(i);
    }
    return res;
};
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 单调栈
    1. 1.1. 解题思路
    2. 1.2. 图解
    3. 1.3. 复杂度
    4. 1.4. 代码实现