Question
Implement the following operations of a stack using queues.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- empty() -- Return whether the stack is empty.
Example:
MyStack stack = new MyStack();
stack.push(1);
stack.push(2);
stack.top(); // returns 2
stack.pop(); // returns 2
stack.empty(); // returns false
Notes:
- You must use only standard operations of a queue -- which means only
push to back,peek/pop from front,size, andis emptyoperations are valid. - Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
- You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).
Solution
- queue的先进先出策略与stack的后进先出策略正好相反。
- 使用double queues的方法模拟stack时,2个队列的空间不是必需的,也可以通过in-place的方法实现。
- 在MyStack push的时候,将新加入的元素用循环移位的方法从back移动到front。具体方法是一个queue的pop-push循环。
- 在使用double queues的情况下有两种选择:
- 新加入的元素放于queue的front处,从front到back,元素从新到旧排列。这种情况push的时间代价为O(N),pop的时间代价为O(1)。
- 新加入的元素放在queue的back处,从front到back,元素从旧到新排列。在push的时候需要通过一个pop-push循环获得最新的元素。这种情况push的时间代价O(1),pop的时间代价为O(N)。
- 新加入的元素放于queue的front处,从front到back,元素从新到旧排列。这种情况push的时间代价为O(N),pop的时间代价为O(1)。
- C++ STL中的queue、stack的
push()和pop()均没有返回值
In-place solution
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
q = new queue<int>;
}
~MyStack() {delete q;}
/** Push element x onto stack. */
void push(int x) {
q->push(x);
int item = 0;
for (int i=q->size()-1;i>0;i--) {
item = q->front();
q->pop();
q->push(item);
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int item = q->front();
q->pop();
return item;
}
/** Get the top element. */
int top() {
return q->front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q->empty();
}
private:
queue<int> *q;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
2 queues solution1
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
q = new queue<int>;
}
~MyStack() {delete q;}
/** Push element x onto stack. */
void push(int x) {
queue<int> *tmp = new queue<int>;
int item =0;
tmp->push(x);
while(!q->empty()) {
item = q->front();
q->pop();
tmp->push(item);
}
delete q;
q = tmp;
}
/** Removes the element on top of the stack and returns that that element. */
int pop() {
int item = q->front();
q->pop();
return item;
}
/** Get the top element. */
int top() {
return q->front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q->empty();
}
private:
queue<int> *q;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
2 queues solution2
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
q = new queue<int>;
}
~MyStack() {delete q;}
/** Push element x onto stack. */
void push(int x) {
q->push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
queue<int> *tmp = new queue<int>;
int item =0;
while(q->size()>1) {
item = q->front();
q->pop();
tmp->push(item);
}
item = q->front();
delete q;
q = tmp;
return item;
}
/** Get the top element. */
int top() {
return q->back();
}
/** Returns whether the stack is empty. */
bool empty() {
return q->empty();
}
private:
queue<int> *q;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/