1.用兩個棧來實現一個隊列
要求: 完成隊列的Push和Pop操作。( 隊列中的元素爲int類型)
對於這個問題,《劍指offer》上有一張圖很形象:
在圖中可以看出它用stack1來模擬入隊列,用stack2來模擬出隊列。然後注意兩點就可以很容易的完成這個問題:
- 1.push( )操作,直接將數據壓入stack1即可;
- 2.pop( )操作,將stack1中的數據彈出然後再壓入到stack2中,這樣數據在兩個棧中順序就相反了,這樣就保證了stack2()棧頂元素一直是最先進隊列的元素,爲保證最先進入的數據一直處於棧頂,只有將stack2中的數據全部pop後,才能繼續講stack1中的數據壓入到stack2中,繼續做pop()。
代碼:
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node); //入隊列,直接將數據壓入stack1()中
}
public int pop() {
if(stack2.empty()) { //stack2棧頂一直是最先進入隊列的元素,爲保證出隊列時它能第一個出,所以它只要不爲空,stack1中的元素就得老實待着,不能彈出到stack2中。
while(!stack1.empty()) { //stack2空了之後,stack1棧底元素就成了最先進入隊列的元素,此時就可以將stack1中的數據全部彈出到stack2中。這樣stack2的棧頂元素又是最先進入隊列的元素了。
stack2.push(stack1.pop());
}
}
return stack2.pop(); //由於有了上面前提,stack2棧頂元素,一直都是最先進入隊列的元素。
}
}
2.用兩個隊列來實現一個棧
題目鏈接:LeetCode 225
要求實現以下功能:
- push(x) – 元素 x 入棧
- pop() – 移除棧頂元素
- top() – 獲取棧頂元素
- empty() – 返回棧是否爲空
做法:
- 入棧:類似於上面用棧實現隊列,這裏直接把數據入q1;
- 出棧:模擬出棧操作大概可以分三步:
第一步:將q1中的元素留一個,剩下的全部出隊,進入q2。 留一個是因爲,出棧順序是先入後出,先把它之前的所有元素搬走,再將它出隊列,就完成了出棧操作;
第二步:將q1中剩下的最後一個元素出隊列,就完了出棧操作。 (因爲他就是最後一個進入棧的元素);
第三步:交換q1,q2。 前面已經可以完成出棧操作,爲什麼還會有這個第三步呢?因爲爲了省事,如果不交換,每次都要再出棧都要判斷兩個隊列哪個不爲空。很麻煩。
代碼:
class MyStack {
private Queue<Integer> q1;
private Queue<Integer> q2;
/** Initialize your data structure here. */
public MyStack() {
q1 = new LinkedList<>();
q2 = new LinkedList<>(); //在構造函數裏給兩個隊列初始化
}
/** Push element x onto stack. */
public void push(int x) {
q1.offer(x); //入棧就直接把元素放進q1
}
/** Removes the element on top of the stack and returns that element. */
//模擬出棧操作大概可以分三步:
//第一步:將q1中的元素留一個,剩下的全部出隊,進入q2。 留一個是因爲,出棧順序是先入後出,先把它之前的所有元素搬走,再將它出隊列,就完成了出棧操作。
//第二步:將q1中剩下的最後一個元素出隊列,就完了出棧操作。 (因爲他就是最後一個進入棧的元素)
//第三步:交換q1,q2。 前面已經可以完成出棧操作,爲什麼還會有這個第三步呢?因爲爲了省事,如果不交換,每次都要再出棧都要判斷兩個隊列哪個不爲空。很麻煩。
public int pop() {
while(q1.size()>1) { //第一步:q1隊尾留下,剩下的全部進入q2
q2.offer(q1.poll());
}
int ret = q1.poll(); //第二步:將剛剛那個留下的隊尾元素出隊。
Queue<Integer> temp = q1;
q1 = q2;
q2 = temp; //第三步:交換q1,q2
return ret;
}
/** Get the top element. */
//獲取棧頂元素
public int top() {
//第一步將q1中size-1個元素搬移到q2中
while(q1.size()>1) {
q2.offer(q1.poll());
}
//獲取q1隊頭元素
int ret = q1.peek();
//將其搬運到q2
q2.offer(q1.poll());
//第三步交換q1,q2,不交換的話話在插的時候就需要考慮哪個隊列不爲空插哪個很麻煩,直接暴力一點,交換省事。
Queue<Integer> temp = q1;
q1 = q2;
q2 = temp;
return ret;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return q1.isEmpty();
}
}
/**
* 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();
* boolean param_4 = obj.empty();
*/