Implement the following operations of a queue using stacks.
- push(x) -- Push element x to the back of queue.
- pop() -- Removes the element from in front of queue.
- peek() -- Get the front element.
- empty() -- Return whether the queue is empty.
Example:
MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); // returns 1 queue.pop(); // returns 1 queue.empty(); // returns false
这一题和Implement Stack using Queues一样是cc150原题,既没营养又没啥实际意义。orz...
和Implement Stack using Queues不同的是那一题我们只需要一个queue就可以了。但这一题一个stack是解决不了问题的,所以人家都告诉你用stacks而不是stack。在这里,我们需要的是两个stack,一个负责装,另一个负责出。
我举个例子,如果我不停push, push了 5, 4, 3, 2, 1。此时stack1里面就是长这样子: 5->4->3->2->1,1在最外面,5在最里面。但作为一个假的queue,你希望的是5在最外面,1在最里面。所以你做了一件事,就是把stack1倒进stack2里面,这个时候stack2里面就变成了: 1->2->3->4->5,变成了你想要的样子。最先进来的数字又变成了最先出去的数字。这就是stack变queue的原理。所以整个算法流程如下:
1. 如果有数字进来要做push,就push到stack1里面。
2. 如果有东西要pop或者peek,就看看stack2有没有东西,有的话就返回pop或者peek,没有的话就把stack1的东西倒过去再进行。
根据上述流程,给出代码如下:
class MyQueue {
Stack<Integer> stk;
Stack<Integer> curStk;
/** Initialize your data structure here. */
public MyQueue() {
stk = new Stack<Integer>();
curStk = new Stack<Integer>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stk.push(x);
}
private void _transferStack() {
if (curStk.isEmpty()) {
while (!stk.isEmpty()) {
curStk.push(stk.pop());
}
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
this._transferStack();
return curStk.isEmpty() ? 0 : curStk.pop();
}
/** Get the front element. */
public int peek() {
this._transferStack();
return curStk.isEmpty() ? 0 : curStk.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return curStk.isEmpty() && stk.isEmpty();
}
}