問題描述:實現一個棧,要求Push(入棧),Pop(出棧),Min(返回最小值的操作)的時間複雜度爲O(1)
分析問題:要記錄從當前棧頂到棧底元素的最小值,很容易想到用一個變量,每push一個元素更新一次變量的值。那麼問題來了,當執行pop操作時,上一次的最小值就找不到了。
解決問題:這裏有兩種方法解決這個問題
方法一
使用一個棧。元素x入棧時,執行一次push(x),再push(min),min表示當前棧頂到棧底元素最小值;元素出棧時,執行兩次pop()
舉個栗子,如果我們要入棧的元素序列是遞增的(1,2,3……1000),那麼每一次入棧都要push(1),操作冗餘。
方法二
使用兩個棧s1和s2,s2做爲輔助棧(每次壓入s2的都是s1的最小值)。元素x入棧時,將x和s2棧頂元素做比較,如果x小於等於s2.top(),將x分別push到s1和s2,否則x只push到s1
;元素出棧時,將s1棧頂元素和s2棧頂元素做比較,如果s1.top()等於s2.top(),s1和s2都執行pop操作,否則只執行s1.pop()
代碼實現(方法二)
#include<iostream>
#include<stack>
using namespace std;
typedef int T;
class StackWithMin
{
public:
StackWithMin()
{}
~StackWithMin()
{}
void Push(T x)
{
s1.push(x);
if (s2.empty() || x <= s2.top())
{
s2.push(x);
}
}
void Pop()
{
if (s1.top() == s2.top())
{
s2.pop();
}
s1.pop();
}
T Min()
{
if (!s2.empty())
{
return s2.top();
}
}
void Print()
{
while (!s1.empty())
{
cout << s1.top() << "->";
s1.pop();
}
cout << endl;
while (!s2.empty())
{
cout << s2.top() << "->";
s2.pop();
}
cout << endl;
}
private:
stack<T> s1, s2;
};
void Test()
{
StackWithMin s;
s.Push(4);
s.Push(3);
s.Push(5);
s.Push(2);
s.Push(1);
s.Push(1);
s.Print();
}
int main()
{
Test();
system("pause");
return 0;
}