劍指Offer(面試題9-1)
題目
請用棧實現一個隊列,支持如下四種操作:
- push(x) – 將元素x插到隊尾;
- pop() – 將隊首的元素彈出,並返回該元素;
- peek() – 返回隊首元素;
- empty() – 返回隊列是否爲空;
注意:
- 你只能使用棧的標準操作:
push to top
,peek/pop from top
,size
和is empty
; - 如果你選擇的編程語言沒有棧的標準庫,你可以使用
list
或者deque
等模擬棧的操作; - 輸入數據保證合法,例如,在隊列爲空時,不會進行
pop
或者peek
等操作;
樣例
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // returns 1
queue.pop(); // returns 1
queue.empty(); // returns false
思路
在做這道題之前,我們應該先搞清楚棧和隊列的特點:棧是一種後入先出的數據結構,而隊列是一種先入先出的數據結構
我們可以通過兩個棧來實現一個隊列,st1
作爲接收入隊元素的棧,st2
作爲控制出隊元素的棧,當我們要入隊時,就將入隊元素壓入st1
中,這時我們發現,如果需要出隊,根據隊列先入先出的特性,st1
的棧底元素需要最先被彈出,這時就要用到第二個棧st2
了,我們將st1
中所有的元素全部出棧,並依次壓入st2
,可以發現,因爲棧是後入先出的數據結構,st1
的棧頂元素會被壓入st2
的棧底, 而我們要得到的最先入隊的元素,也就是原st1
的棧底元素,此時在st2
的棧頂,我們直接對st2
進行出棧操作,就可以得到需要出隊的元素了
這裏我們需要注意,每次出棧時,我們應該先檢測st2
中是否還有值,如果有值我們就不需要將st1
的元素壓入st2
中,直接從st2
出棧即可,下面是代碼,這裏我是用 Java 中自帶的棧,使用數組模擬棧也是完全可以的
代碼
class MyQueue {
private Stack<Integer> st1;
private Stack<Integer> st2;
/** Initialize your data structure here. */
public MyQueue() {
st1 = new Stack<Integer>();
st2 = new Stack<Integer>();
}
/** Push element x to the back of queue. */
public void push(int x) {
st1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (st2.empty()) {
while (!st1.empty())
st2.push(st1.pop());
}
return st2.pop();
}
/** Get the front element. */
public int peek() {
if (st2.empty())
while (!st1.empty())
st2.push(st1.pop());
return st2.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
if (st1.empty() && st2.empty()) return true;
return false;
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/