【LeetCode】【最小栈】

发布于:2022-11-29 ⋅ 阅读:(337) ⋅ 点赞:(0)

155. 最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/min-stack
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这里我们的方式是定义一个辅助站,如果新的元素插入的时候比我们原有的辅助栈的栈顶元素小,辅助栈就入栈,如果比辅助栈的栈顶元素更大,就不入栈。

在出栈的时候,如果辅助栈的栈顶元素和原有栈的栈顶元素相等的话,就弹出栈。 

class MinStack {
public:
    //这个删掉也能过,因为它会默认生成一个minstack()
    MinStack() {

    }
    
    void push(int val) {
        _st.push(val);
        if(_minst.empty()|| val <=_minst.top())
        {
            _minst.push(val);
        }

    }
    
    void pop() {
        if(_minst.top()==_st.top())
        {
            _minst.pop();
        }
        _st.pop();
    }
    
    int top() {
        return _st.top();
    }
    
    int getMin() {
        return _minst.top();
    }
private:
    stack<int> _st;
    stack<int> _minst;
};
//如果说我有大量的重复数据应该怎么办
//比方说我们插入了10w个1
//我们这道题有没有优化的空间
//可以加一个计数器
//也就是说这个minst中,新的数据栈顶元素小就更新,比栈顶元素大就不更新,跟栈顶元素相等就让计数器++

 

 

一开始我也是认为上面这种算法就可以了,因为可以通过测试用例了,直到一位读者给我指出了优化的方向,再次真的非常感谢这位读者提出的宝贵建议

然后也就是说,如果我们的入栈顺序是3->2->2->1,然后这样的话,我们的最小栈也是要入3->2->2->1这样重复的栈就会导致我们的空间开销非常大。

在此我们采用二元组的形式pair,每一次入栈,就判断一下当前元素是否比最小栈栈顶的元素小,如果比最小栈的栈顶元素小,我们就往最小栈的栈顶push一个二元组,二元组的第一个位置记录当前push进去的元素是什么,第二个位置记录当前push的元素一共有几个

这样的话,我们上面的3->2->2->1中,我们的2就变成用二元组<2,2>来记录了,当pop的时候,也是如果主栈pop了一次2,那么我们的最小栈栈顶的<2,2>变成<2,1>,当主栈再pop一次2,那我们的最小栈就将<2,1>整个弹出。

class MinStack {
public:
    //这个删掉也能过,因为它会默认生成一个minstack()
    MinStack() {

    }
    
    void push(int val) {
        _st.push(val);
        if(_minst.empty()|| val <_minst.top().first)
        {
            pair<int, int> tmp = make_pair(val, 1);
            _minst.push(tmp);
        }
        else if(val==_minst.top().first)
        {
            _minst.top().second++;
        }

    }
    
    void pop() {
        if(_minst.top().first==_st.top())
        {
            if(_minst.top().second==1)
            {
                _minst.pop();
            }
            else{
                _minst.top().second--;
            }
        }
        _st.pop();
    }
    
    int top() {
        return _st.top();
    }
    
    int getMin() {
        return _minst.top().first;
    }
private:
    stack<int> _st;
    stack<pair<int,int>> _minst;
};
//如果说我有大量的重复数据应该怎么办
//比方说我们插入了10w个1
//我们这道题有没有优化的空间
//可以加一个计数器
//也就是说这个minst中,新的数据栈顶元素小就更新,比栈顶元素大就不更新,跟栈顶元素相等就让计数器++

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

可以看到现在的代码的效率比之前高了很多。

 

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到