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.
- You must use only standard operations of a queue -- which means only
push to back
,peek/pop from front
,size
, andis empty
operations 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).
算法一:在pop()操作上下功夫
队列,插入后,元素位于末尾。
按照栈后进先出原则,此队尾的元素,当最先被删除。
而队列的删除操作只能在队头发生。
那只需要将整个队列进行循环移动操作(类似位运算的循环移位)。
设队列的元素个数为n,当时行n-1次循环移位操作,末尾的数就被移到了队头。然后作删除。
当然,正向移动n-1位,结果也相当于,反向移动1位。即,末尾元素跑到队头,其他元素顺序向后移动一个位置。
class Stack {
queue<int> q_;
public:
// Push element x onto stack.
void push(int x) {
q_.push(x);
}
// Removes the element on top of the stack.
void pop() {
int size = q_.size();
while (--size) {
q_.push(q_.front());
q_.pop();
}
q_.pop();
}
// Get the top element.
int top() {
return q_.back();
}
// Return whether the stack is empty.
bool empty() {
return q_.empty();
}
};
算法二,在push时下功夫
在将元素插入在队尾,并将整个队列正向移动n-1个位置。(设整个队列元素个数为n) 。
从逻辑上讲,正向移动n-1个位置,相当于反向移动1个位置。
即,队尾的元素移动了队头,其他元素向后顺序移动一个位置。
从而达到了插入总是在对头完成。
即总是将元素插入了队头。而出队也是发生在队头。这就实现了栈的LIFO。
class Stack {
queue<int> q_;
public:
// Push element x onto stack.
void push(int x) {
q_.push(x);
int n = q_.size();
while (--n) {
q_.push(q_.front());
q_.pop();
}
}
// Removes the element on top of the stack.
void pop() {
q_.pop();
}
// Get the top element.
int top() {
return q_.front();
}
// Return whether the stack is empty.
bool empty() {
q_.empty();
}
};