C++圖解:劍指Offer09. 用兩個棧實現隊列

原題LeetCode鏈接:劍指Offer09. 用兩個棧實現隊列

題目:用兩個棧實現隊列

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTaildeleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,deleteHead 操作返回 -1 )

示例1:
輸入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
輸出:[null,null,3,-1]
示例2:
輸入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
輸出:[null,-1,null,null,5,2]
  • 1 <= values <= 10000
  • 最多會對 appendTail、deleteHead 進行 10000 次調用

思路

​ 棧具有“後進先出”的特性,隊列具有“先進先出”的特性。

​ 題目要求是使用兩個棧,我們假設它們分別是s1,s2。棧本身和隊列一樣也是一種順序結構,不考慮操作的話其實隊列與棧它們內部的元素順序是相同的。所以向一個棧中插入數據的操作就可以當作隊列的插入操作。

​ 那麼我們可以主要使用s1來實現,s2作爲輔助結構。

在這裏插入圖片描述

​ 當向s1中插入數據時,元素順序與插入隊列的順序一致,故可以當做是隊列的插入元素操作。

在這裏插入圖片描述

​ 要想做到隊列的刪除,就不能簡單地彈出棧中元素。“先進後出,後進先出”,組合一起就是“先進先出”。我們可以用s2來輔助顛倒一次,即從s1中彈出後立即進入s2。如下圖:

在這裏插入圖片描述

​ 這樣,彈出s2中的’6’就相當於隊列的隊首出隊。以上就實現了隊列的插入和刪除功能,最後別忘了將s2中的元素再插入回s1。

C++代碼

class CQueue {
public:
    stack<int> s1, s2;
    //在s1插入
    CQueue() {

    }
    
    void appendTail(int value) {
        s1.push(value);
    }
    
    int deleteHead() {
        if(s1.empty()) return -1;
        while(!s1.empty()){
            s2.push(s1.top());
            s1.pop();
        }
        int res = s2.top();
        s2.pop();
        while(!s2.empty()){
            s1.push(s2.top());
            s2.pop();
        }
        return res;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

複雜度分析:

時間複雜度:插入元素就是直接插入即可,時間複雜度就是O(1);刪除元素的話需要對所有元素進行兩次轉移,時間複雜度就是O(n)。

空間複雜度:插入元素僅在s1上,沒用到s2,空間複雜度是O(1).刪除元素時用到兩s2,空間複雜度O(n)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章