栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。
示例1:
示例2:
先设置主栈为st,辅助栈为help。如果主栈为空,我们直接往主栈中遍历元素。如果主栈中有元素,则逐一比较与栈顶元素的大小。如果这个值大于栈顶元素,则栈顶元素弹出,并压入辅助栈中。如果这个元素小于等于主栈顶元素了话,我们就直接往主栈中添加元素。
具体实现看代码:
class SortedStack {
public:stack st;stack help;SortedStack() {}void push(int val) {while(!st.empty() && val > st.top()){help.push(st.top());st.pop();}st.push(val);while(!help.empty()){st.push(help.top());help.pop();}}void pop() {if(st.empty()) return;st.pop();return;}int peek() {if(st.empty()) return -1;return st.top();}bool isEmpty() {return st.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();*/
复杂度分析:
时间复杂度:push方法的时间复杂度最小为O(1),最大为O(2N),其中N是压入栈的元素。push方法均摊下来的时间复杂度为O(N)。pop,peek,isempty方法的时间复杂度均是O(1)
空间复杂度:我们需要用到两个栈,我们需要往这个栈中添加元素。所以空间复杂度为O(N),N为往栈中压的元素数量。
那如何不使用辅助栈呢?我觉得大家心里大概会有一个答案。那就是递归!!!
那首先,我先来说一下,我理解的递归函数三要素是什么
然后我们来看这道题。
那对于这道题来说,我们要做的就是,使栈中的元素从顶到底,永远是按照从小到大排列。
那么我们要解决的大问题就是将栈中的元素从顶到底,永远是从小到大排列。那小问题是什么呢?小问题就是,我们每次都要去比较要压入栈的元素与栈顶的元素去做比较。如果大于栈顶元素,就继续递归。如果小于,就直接添加到栈顶。
我们现在将单层递归的逻辑想清楚了后,那我们想一想递归函数如何结束呢?那当然是将val加入栈后,就结束了啊。
最后我们来想想这个函数需要什么返回值,与形参。那么根据这道题,我发现直接使用原函数的push方法就行了。
ok,想明白这所有的问题后,就不难写出代码了,下面是具体的代码:
class SortedStack {
public:stack st;SortedStack() {}void push(int val) {if(!st.empty() && val > st.top()){int temp = st.top();st.pop();push(val);st.push(temp);return ;}st.push(val);return;}void pop() {if(!st.empty()) st.pop();return ;}int peek() {if(st.empty()) return -1;return st.top();}bool isEmpty() {return st.empty();}
};
复杂度分析:
时间复杂度:push方法的时间复杂度为O(n),n为要添加进栈的元素。pop,peek,isempty方法的时间复杂度均为O(1)。
空间复杂度:O(n) ,n是压入栈的元素
这道题需要我们对栈这种数据结构的用法要比较了解。同时对递归函数的写法要心中有思路。做到了这两点,这道题其实没有什么难度。
上一篇:map 、multimap
下一篇:我又和redis超时杠上了