題目要求
實現一個棧,要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度爲O(1)
首先針對這道題有多重解決方案。
1、定義兩個棧,一個正常棧,另一個棧的棧頂始終保存整個棧內的最小值。
思路如下:
- 無論Push什麼數據,正常棧肯定直接Push進去。
- 而當新Push的數據大於最小棧的棧頂時,最小棧將自己的棧頂再次Push一遍。
- 而當新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;
};