• 剑指 Offer 30. 包含min函数的栈 && Leetcode 155. 最小栈


    地址  https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/

    定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
    
     
    
    示例:
    
    MinStack minStack = new MinStack();
    minStack.push(-2);
    minStack.push(0);
    minStack.push(-3);
    minStack.min();   --> 返回 -3.
    minStack.pop();
    minStack.top();      --> 返回 0.
    minStack.min();   --> 返回 -2.
     
    
    提示:
    
    各函数的调用总次数不超过 20000 次
     
    
    注意:本题与主站 155 题相同:https://leetcode-cn.com/problems/min-stack/
    
     

    解答

    栈的操作基本没有变化 ,关键在于如何获取当前序列中最小的数。

    最开始考虑使用最小堆,但是最小堆的弹出的时间复杂度达不到题目要求

    我们从减少最小堆的不必要的存储和弹出的操作入手。如果当前push 的数据比最小堆的顶端最小数目大的话那么就不必push进入堆,

    因为该数字push进容器内,它在容器内的存活周期中他的下面始终有一个存活周期比它长比他小的数字,所以它的push和pop是没有必要的

    于是就可以大量减少最小堆的操作。

    代码如下

    class MinStack {
    public:
        /** initialize your data structure here. */
        stack<int>data;
        priority_queue<int, vector<int>, greater<int>> minHeap;
        MinStack() {
        }
    
        void push(int x) {
            data.push(x);
            if (minHeap.empty() || x <= minHeap.top() ) minHeap.push(x);
        }
    
        void pop() {
            if (data.empty()) return;
            int x = data.top(); data.pop();
            if (x <= minHeap.top()) minHeap.pop();
        }
    
        int top() {
            return data.top();
        }
    
        int min() {
            if (!minHeap.empty())
                return minHeap.top();
    
            return -999999;
        }
    };

    进一步的优化,观察以上的堆的操作

    堆的操作已经演变成一个只记录当前最小数字的单调栈了

    那么直接使用两个栈就可以完成以上操作

    ========================================================================================

    class MinStack {
    public:
        /** initialize your data structure here. */
        stack<int>data;
        stack<int>currMin;
        MinStack() {
        }
    
        void push(int x) {
            data.push(x);
            if (currMin.empty() || x <= currMin.top() ) currMin.push(x);
        }
    
        void pop() {
            if (data.empty()) return;
            int x = data.top(); data.pop();
            if (x <= currMin.top()) currMin.pop();
        }
    
        int top() {
            return data.top();
        }
    
        int min() {
            if (!currMin.empty())
                return currMin.top();
    
            return -999999;
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    C#开发Activex控件疑难杂症
    spring、struts、mybatis、Postgresql集成使用存储过程进行分页
    C#开发Activex控件升级
    通过Maven将Web程序部署到远程Tomcat8服务器的一些注意事项
    分页存储过程Oracle版
    JSP EL表达式(转)
    关于Log4x
    C#类在初始化时的执行顺序
    使用MSMQ 远程队列
    tomcat部署与Context(转)
  • 原文地址:https://www.cnblogs.com/itdef/p/14403498.html
Copyright © 2020-2023  润新知