面试题 03.05. 栈排序
题目:
栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。
示例1:
输入:
["SortedStack", "push", "push", "peek", "pop", "peek"]
[[], [1], [2], [], [], []]
输出:
[null,null,null,1,null,2]
示例2:
输入:
["SortedStack", "pop", "pop", "push", "pop", "isEmpty"]
[[], [], [], [1], [], []]
输出:
[null,null,null,null,null,true]
说明:
栈中的元素数目在[0, 5000]范围内。
解答:
方法1:
堆排序,复杂度n*logn(n次操作,pop_heap最大logn)
class SortedStack { public: vector<int> data; SortedStack() { } void push(int val) { data.push_back(val); make_heap(data.begin(),data.end(),[](const int& a,const int& b){return a>b;}); } void pop() { if(data.empty()){ return; } pop_heap(data.begin(),data.end(),[](const int& a,const int& b){return a>b;}); data.pop_back(); } int peek() { if(data.empty()){ return -1; } return data[0]; } bool isEmpty() { return data.empty(); } }; /** * Your SortedStack object will be instantiated and called as such: * SortedStack* obj = new SortedStack(); * obj->push(val); * obj->pop(); * int param_3 = obj->peek(); * bool param_4 = obj->isEmpty(); */
注:下面两个方法代码不是我写的
方法2:
每次push都直接排序,复杂度n^2(n,n-1,n-2,n-3...3,2,1这样倒序push的情况)
class SortedStack { private: stack<int> data; stack<int> help; public: SortedStack() { } void push(int val) { if (!data.empty() && val > data.top()) { while (!data.empty() && val > data.top()) { int temp = data.top(); data.pop(); help.push(temp); } data.push(val); while (!help.empty()) { int temp = help.top(); help.pop(); data.push(temp); } } else { data.push(val); } } void pop() { if (!data.empty()) { data.pop(); } } int peek() { if (!data.empty()) { return data.top(); } else { return -1; } } bool isEmpty() { return data.empty(); } };
方法3:
等到pop再排序,即有连续的push先不排序,先在辅助栈里攒着。如果需要pop了,把辅助栈的数字一股脑push到主栈。再pop。
class SortedStack { private: stack<int>s1;//原栈为升序 stack<int>s2;//辅助栈为降序 public: SortedStack() { } void push(int val) { while(!s2.empty()&&s2.top()>val){//辅助栈中存在比val大的值 s1.push(s2.top()); s2.pop(); } while(!s1.empty()&&s1.top()<val){//原栈中有比val小的值 s2.push(s1.top()); s1.pop(); } s1.push(val); } void pop() { while(!s2.empty()){//清空辅助栈 s1.push(s2.top()); s2.pop(); } if(!s1.empty()) s1.pop(); } int peek() { while(!s2.empty()){//清空辅助栈 s1.push(s2.top()); s2.pop(); } if(!s1.empty()) return s1.top(); else return -1; } bool isEmpty() { return s1.empty()&&s2.empty(); } };
进击的小🐴农