问题描述
给栈结构设计一个求最小值的操作,要求入栈、出栈以及求最小值均在O(1)完成。
给出策略利用栈去完成一个序列的排序,并分析相应的性能。
解题思路
第一题
维护两个栈,一个是普通栈 normalStack
,一个是小顶栈 minStack
。
入栈操作就是normalStack
正常push,minStack
当栈为空或栈顶元素比要入栈小时push进去。
这样就可保证minStack
的top为最小值,且入栈操作时间复杂度为O(1)。
出栈操作normalStack
同理正常pop,minStack
当top元素的值等于normalStack
的top元素时就出栈。
这样就可以保证每次pop弹出元素后minStack
的top仍为最小值。时间复杂度为O(1)。
求最小值只需要返回minStack
的top即可。时间复杂度为O(1)。
第二题
使用栈进行排序的一个常见策略是利用一个额外的临时栈,将原始栈中的元素依次弹出并按顺序插入到辅助栈中。具体步骤如下:
维护两个栈,一个是主栈mainStack
,一个是临时栈tempStack
。
入栈时,如果mainStack
主栈为空或者要入栈的元素x小于栈顶,就直接push到mainStack
。
否则,将mainStack
上方小于x的所有元素依次弹出,再push到tempStack
中去,然后将x压入mainStack
中,
再将tempStack
中的所有元素依次pop再push到mainStack
中。最后得到从栈顶到栈底从小到大的排序。
入栈操作需要将mainStack
的元素倒出来,再到回去,时间复杂度为O(2n),去掉常量为O(n),
一共有n个元素,所以总的时间复杂度为O($n^2$)。
完整代码
T1
C++源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <stack> #include <iostream>
using namespace std;
class MinStack { private: stack<int> normalStack; stack<int> minStack;
public:
void push(int x) { normalStack.push(x); if (minStack.empty() || x <= minStack.top()) { minStack.push(x); } }
void pop() { if (normalStack.top() == minStack.top()) { minStack.pop(); } normalStack.pop(); }
int top() { return normalStack.top(); }
int getMin() { return minStack.top(); } };
int main() { MinStack minStack; int n; cout<<"请输入元素个数:"; cin>>n; for(int i=1;i<=n;i++){ int x; cin>>x; minStack.push(x); cout<<"当前最小值:"<<minStack.getMin()<<endl; } return 0; }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11
| 请输入元素个数:5 8 当前最小值:8 2 当前最小值:2 4 当前最小值:2 5 当前最小值:2 1 当前最小值:1
|
T2
C++源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <stack> #include <iostream>
using namespace std;
stack<int> mainStack;
class SortStack { private: stack<int> tempStack; public: void push(int x) { if(mainStack.empty() || x <= mainStack.top()){ mainStack.push(x); } else{ while(!mainStack.empty() && mainStack.top() <= x){ tempStack.push(mainStack.top()); mainStack.pop(); } mainStack.push(x); while(!tempStack.empty()){ mainStack.push(tempStack.top()); tempStack.pop(); } } }
};
int main() { int n; SortStack sortStack; cout<<"请输入元素个数:"; cin>>n; cout<<"请输入"<<n<<"个元素:"<<endl; for(int i=1;i<=n;i++){ int x; cin>>x; sortStack.push(x); } for(int i=1;i<=n;i++){ cout<<mainStack.top()<<" "; mainStack.pop(); } return 0; }
|
运行结果
1 2 3 4
| 请输入元素个数:5 请输入5个元素: 2 1 3 5 4 1 2 3 4 5
|