實現最小棧

題目要求

實現一個棧,要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度爲O(1)

首先針對這道題有多重解決方案。
1、定義兩個棧,一個正常棧,另一個棧的棧頂始終保存整個棧內的最小值。

思路如下:

  1. 無論Push什麼數據,正常棧肯定直接Push進去。
  2. 而當新Push的數據大於最小棧的棧頂時,最小棧將自己的棧頂再次Push一遍。
  3. 而當新Push的數據小於最小棧的棧頂時,意思是該數據現在是整個棧中的最小值,則將該值也直接Push進最小棧

這裏寫圖片描述

這種思路的Pop和就很簡單了,每次Pop時,將兩個棧的棧頂都Pop出去就好了,求Min的話,直接返回最小棧的棧頂。

基於這種思路,寫出如下代碼:

template<class T>
class MinStack
{
public:
    void Push2(const T value)
    {
        if (_s.empty() || _min.top() > value)
        {
            _s.push(value);
            _min.push(value);
        }
        else
        {
            _s.push(value);
            _min.push(_min.top());
        }

    }

    void Pop()
    {
        _s.pop();
        _min.pop();
    }

    T Min()
    {
        return _min.top();
    }
private:
    stack<T> _s;
    stack<T> _min;
};

2、在第一種的思路中,最小棧將當前最小的值重複存放了好多份,可不可以只存一份呢?加上引用計數!
如果直接只存一份的話,會出現下面這種情況。
每次Pop時,如果待Pop的值大於最小棧中的棧頂數據,就只Pop正常棧,但是如果棧中有兩個相同元素呢?

這裏寫圖片描述

template <class T>
class MinStack
{
public:
    void Push(const T value)
    {
        if (_s.empty() || _min.top().first > value)
        {
            _s.push(value);
            _min.push(make_pair(value, 1));
        }
        else if (_min.top().first == value)
        {
            _s.push(value);
            _min.top().second += 1;
        }
        else
        {
            _s.push(value);
        }
    }

    void Pop()
    {
        T top = _s.top();
        if (top == _min.top().first)
        {
            if (_min.top().second > 1)
                --_min.top().second;
            else
                _min.pop();

            _s.pop();
        }
        else
        {
            _s.pop();
        }
    }

    int Min()
    {
        return _min.top().first;
    }
private:
    stack<int> _s;
    stack<pair<int, int>> _min;
};

3、使用一個棧,每次Push兩個值,一個正常值,一個是最小值,什麼意思呢?

template <class T>
class MinStack
{
public:
    void Push(const T value)
    {
        if (_s.empty() || _s.top() > value)
        {
            _s.push(value);
            _s.push(value);
        }
        else
        {
            T top = _s.top();
            _s.push(value);
            _s.push(top);
        }
    }

    void Pop()
    {
        _s.pop();
        _s.pop();
    }

    int Min()
    {
        return _s.top();
    }
private:
    stack<int> _s;
};

4、基於第三種方法,可以每次Push一個鍵值對,一個保存正常值,一個保存最小值,和第三種思想是一樣的。

template <class T>
class MinStack
{
public:
    void Push(const T& value)
    {
        if (_s.empty() || _s.top().second > value)
        {

            _s.push(make_pair(value, value));
        }
        else
        {
            _s.push(make_pair(value, _s.top().second));
        }
    }

    void Pop()
    {
        _s.pop();
    }

    T Min()
    {
        return _s.top().second;
    }
private:
    stack<pair<int, int>> _s;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章