1. 程式人生 > 實用技巧 >[leetcode/lintcode 題解] Google 面試題:用棧實現佇列

[leetcode/lintcode 題解] Google 面試題:用棧實現佇列

正如標題所述,你需要使用兩個棧來實現佇列的一些操作。 佇列應支援push(element),pop() 和 top(),其中pop是彈出佇列中的第一個(最前面的)元素。 pop和top方法都應該返回第一個元素的值。 線上評測地址:領釦題庫官網 例1: 輸入: push(1) pop() push(2) push(3) top() pop() 輸出: 1 2 2 例2: 輸入: push(1) push(2) push(2) push(3) push(4) push(5) push(6) push(7) push(1)
輸出: [] 解題思路 先考慮只有一個棧的時候,由於棧的先入後出特性FILO,棧中的元素的順序是反的,我們無法直接訪問棧底的元素。但是當把1號棧中所有元素依次彈出並壓入到2號棧中,2號棧頂的元素就變成了原來1 號棧的棧底,即正序。所以我們要提取元素時,只需從2號棧提取即可。 但是由於2號棧中棧頂元素是最先加入佇列的元素,所以只有當2號棧為空時,才能將1號棧中所有元素加入到2號棧中。 舉例說明: 首先我們有一個主要棧stack1:[1,2,3) ,以下所有棧的表示方式中,圓括號 ')' 均為棧頂。 那麼stack1的出棧順序為3-2-1,其中 1 為我們要找到的元素,也就是隊首。
我們需要藉助一個輔助棧stack2:[),將stack1中的元素依次放到stack2中:stack2 [3,2,1)。這時我們發現stack2的棧頂就是我們要找的元素,彈出即可。 此時我們再向主要棧stack1中壓入 4 和 5。兩個棧狀態:stack1 [4,5) 、stack2 [3,2)。 現在我們需要隊首的話,應該先彈出輔助棧stack2的棧頂。 如果此時輔助棧空,我們就要執行之前轉移的操作,將stack1的所有元素壓入stack2,然後彈出stack2的棧頂即可。 程式碼思路 定義move(),操作是將元素從1號棧轉移到2號棧。當要提取元素,且2號棧為空時,呼叫move()
複雜度分析 時間複雜度
  • 每個元素最多會別pushpopmove一次,每個操作的均攤時間複雜度為O(1)
空間複雜度
  • 假設一共操作了Npush,空間複雜度為O(N)
public class MyQueue { public MyQueue() { // do intialization if necessary } /* * @param element: An integer * @return: nothing */ public void push(int element) { stack1.push(element); } /* * @return: An integer */ public int pop() { if (stack2.isEmpty()) { move(); } return stack2.pop(); } /* * @return: An integer */ public int top() { if (stack2.isEmpty()) { move(); } return stack2.peek(); } // 將1號棧中的元素移動到2號棧中 private void move() { while (! stack1.isEmpty()) { stack2.push(stack1.pop()); } } private Stack<Integer> stack1 = new Stack<>(); private Stack<Integer> stack2 = new Stack<>(); } 更多題解參考:九章官網solution