单调栈

作者: siliconx | 来源:发表于2020-07-17 13:08 被阅读0次

leetcode - 42. 接雨水
单调栈即元素严格单调递增或单调递减的栈,只需要在元素入栈的时候保持栈的单调性即可(新元素入栈前先把栈中所有比它小的元素弹出)。
对于leetcode第42题,把每一根柱子作为栈元素,形成一个递减的单调栈,即可解决问题。
代码如下,详细解释见注释:

class Solution {  // 单调栈
    public int trap(int[] heights) {
        int h, w, idx, result = 0;
        Element e = null, top1 = null, top2 = null;
        Stack<Element> stack = new Stack<>();

        // 跳过开头所有高度为0的元素,找到第一个非0元素
        for (idx = 0; idx < heights.length; ++idx) {
            if (heights[idx] != 0) break;
        }

        for (; idx < heights.length; ++idx) {
            e = new Element(idx, heights[idx]);  // 新元素

            if (stack.empty()) {
                stack.push(e);
            } else {
                top1 = stack.peek();
                if (top1.val < e.val) {  // 新柱子比栈顶高
                    // 注意出栈时栈里至少要留出一根柱子,否则水就从左边溜走了
                    while (stack.size() > 1 && top1.val < e.val) {
                        stack.pop();
                        top2 = stack.peek();

                        // 高度(top1是底,top2和e是左右两个边)
                        h = Math.min(e.val, top2.val) - top1.val;

                        // 宽度
                        w = e.idx - top2.idx - 1;

                        // 求面积
                        result += h * w;
                        top1 = top2;
                    }

                    if (stack.size() == 1 && top1.val < e.val) {
                        // 如果栈中的最后一个柱子比e矮,直接丢弃
                        stack.pop();
                    }

                    // 新柱子入栈
                    stack.push(e);
                } else if (top1.val == e.val) {
                    // 遇到高度相同的柱子,只需要更新栈顶元素的下标即可
                    // 因为栈里的元素只能作为左侧的边或者底部
                    // 当它作为底时,它的下标不影响计算
                    // 当它作为左侧边时,对于高度一样的柱子,需要选最右的柱子
                    top1.idx = e.idx;
                } else {
                    // 比栈顶元素小,直接入栈
                    stack.push(e);
                }
            }
        }

        return result;
    }
}

class Element {
    // 保存每个柱子的下标和高度
    int idx, val;
    public Element(int idx, int val) {
        this.idx = idx;
        this.val = val;
    }
}

参考:
[1]. https://zhuanlan.zhihu.com/p/26465701

相关文章

  • 单调栈和应用实践

    什么是单调栈 单调栈的定义:单调栈即满足单调性的栈结构。与单调队列相比,其只在一端进行进出。 如何使用单调栈 单调...

  • 1.单调栈

    一、单调栈定义 单调栈(monotone-stack)是指栈内元素(栈底到栈顶)都是(严格)单调递增或者单调递减的...

  • 单调栈 2020-06-12(未经允许,禁止转载)

    1.单调栈 指栈内元素保持单调性的栈结构,分为单调增栈(栈底到栈顶元素递增)和单调减栈(栈底到栈顶元素递减) 2....

  • LeetCode刷题指北----单调栈

    1.什么是单调栈?有什么好处? 定义: 单调栈就是栈内元素递增或者单调递减的栈,并且只能在栈顶操作。单调栈的维护是...

  • C语言之单调栈

    单调栈 What 单调栈也是栈的一种,满足先进后出的原则,另外,单调栈中的元素是有序的,分为两种 单调递增栈:单调...

  • 腾讯笔试--逛街

    主要的知识点是:单调栈,该题牢牢记得:栈中记录当前楼能看到的元素 单调栈是单调递增栈,栈顶是最小值单调栈存的是能看...

  • 题解——单调栈

    单调栈题解 单调栈结构 牛客链接 方法:单调栈 算法 这里维护一个单调递增栈,可以找到比当前元素要小的元约定:当前...

  • 单调栈

    leetcode - 42. 接雨水单调栈即元素严格单调递增或单调递减的栈,只需要在元素入栈的时候保持栈的单调性即...

  • Java版算法模版总结(2)

    本次233酱介绍下单调栈、单调队列、并查集、KMP算法,欢迎交流指正~ 单调栈 「单调栈」首先是一种基于栈的数据结...

  • 单调栈

    对应力扣题目-739. 每日温度 什么是单调栈? 单调递增栈,从栈底到栈顶依次递增(单调非递减栈:允许有相等) 单...

网友评论

      本文标题:单调栈

      本文链接:https://www.haomeiwen.com/subject/zyowhktx.html