Leetcode-155: Min Stack

这题是容易题,但我觉得很值得好好研究。
我开始是想用一个链表来maintain最小值,发现太慢,不能再常数时间内返回,后来又想用一个数组,但是很难插入最小值。参考了答案才恍然大悟。
解法1:用两个栈,其中一个保存当前的最小值。思路比较好懂。
举例如下: 输入数据为arr={10,6,8,7,5,12},则minarr={10,6,6,6,5,5}。当pop()时,minarr跟arr同步pop()即可,一次只需pop一个。

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {
        minarr.push_back(INT_MAX);
    }

    void push(int x) {
       arr.push_back(x);
       if (x<minarr.back())
           minarr.push_back(x);
       else
           minarr.push_back(minarr.back());
    }

    void pop() {
        arr.pop_back();
        minarr.pop_back();
    }

    int top() {
        return arr.back();
    }

    int getMin() {
        return minarr.back();
    }

private:
    vector<int> arr;
    vector<int> minarr;

};

解法2则更为巧妙,只用一个array,但是加了些冗余的元素。
举例如下: 输入数据为{10,6,8,7,5,12},则arr={10, 10, 6, 8, 7, 6, 5, 12}。冗余元素发生在push过程中,当前元素比minv小的时候,我们把旧的minv和当前元素先后push_back到arr里面,并更新minv。当pop()时,如果我们发现arr.back()是minv,则先pop(),然后我们知道下一个就是接下来的minv,我们把minv更新后再把它pop()掉就可以了。
注意:
1) push()中必须用<=,如果我们用<的话,当输入数据为{10,6,8,7,5,5},则arr={10, 10, 6, 8, 7, 6, 5, 5}。那么当pop()的时候,两个5都pop()掉,并且当前的minv又是5,则出错。用了<=后,arr={10, 10, 6, 8, 7, 6, 5, 5, 5},则第一个5 pop()掉后会顺便pop()掉第2个5,此时minv=5,第3个5 pop()的时候会把minv更新为6, 并且顺便把6也pop()掉。
2) 注意vector的pop_back()和back()的用法。我认为pop_back()实际上相当于arr.resize(arr.size()-1),不知对否。

#include <iostream>
#include <climits>
#include <vector>

using namespace std;

class MinStack {
public:
    MinStack():minv(INT_MAX) {}
    void push(int x) {
       if (x<=minv) {
           arr.push_back(minv);
           minv=x;
       }
       arr.push_back(x);
    }

    void pop() {
        int tmp=arr.back();
        arr.pop_back();
        if (tmp==minv) {
            minv=arr.back();
            arr.pop_back();
        }
    }

    int top() {
        return arr.back();
    }

    int getMin() {
        return minv;
    }

private:
    vector<int> arr;
    int minv;
};


int main()
{
   MinStack *obj = new MinStack();
   obj->push(7);
   obj->push(2);
   obj->push(3);
   obj->push(1);
   obj->push(0);

   obj->pop();
   obj->push(5);
   obj->push(4);
   obj->push(3);

   int param_3 = obj->top();
   int param_4 = obj->getMin();

   cout<<param_3<<" "<<param_4<<endl;
   return 0;
}

dsf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值