題目
使用棧實現隊列的下列操作:
push(x) – 將一個元素放入隊列的尾部。
pop() – 從隊列首部移除元素。
peek() – 返回隊列首部的元素。
empty() – 返回隊列是否爲空。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
說明:
你只能使用標準的棧操——也就是隻有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的語言也許不支持棧。你可以使用 list 或者 deque(雙端隊列)來模擬一個棧,只要是標準的棧操作即可。
假設所有操作都是有效的 (例如,一個空的隊列不會調用 pop 或者 peek 操作)。
解題思路
解題之前,我們需要先明白棧和隊列的區別。棧,它的特點是先進後出,即LIFO,而隊列的特點是先進先出,即FIFO。這意味着在進行 pop() 操作時,我們需要彈出的是棧底元素。
如何保證進行 pop() 操作時,彈出棧底元素的同時,保存其他元素及元素順序呢?我們可以用兩個棧來實現。
假設有 stack1 和 stack2 兩個棧,push() 操作都是將元素推送到 stack1 中。那麼 pop() 時,先將 stack1 中的所有元素都取出,再推到 stack2 中,這樣 stack2 中的元素就符合隊列 FIFO 的順序了,我們再對 stack2 進行 pop() 操作即可。
代碼
class MyQueue {
private Stack<Integer> stack1 = new Stack<>();
private Stack<Integer> stack2 = new Stack<>();
private int front;
/**
* Initialize your data structure here.
*/
public MyQueue() {
}
/**
* Push element x to the back of queue.
*/
public void push(int x) {
if (stack1.isEmpty()) {
front = x;
}
stack1.push(x);
}
/**
* Removes the element from in front of queue and returns that element.
*/
public int pop() {
if (!stack2.isEmpty()) {
return stack2.pop();
} else {
while (stack1.size() != 1) {
stack2.push(stack1.pop());
}
return stack1.pop();
}
}
/**
* Get the front element.
*/
public int peek() {
if (!stack2.isEmpty()) {
return stack2.peek();
}
return front;
}
/**
* Returns whether the queue is empty.
*/
public boolean empty() {
return stack1.isEmpty() && stack2.isEmpty();
}
}