【劍指Offer】面試題09. 用兩個棧實現隊列

題目

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,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 次調用

思路

解題思路:
棧無法實現隊列功能: 棧底元素(對應隊首元素)無法直接刪除,需要將上方所有元素出棧。
雙棧可實現列表倒序: 設有含三個元素的棧 A = [1,2,3] 和空棧 B = []。若循環執行 A 元素出棧並添加入棧 B ,直到棧 A爲空,則 A = [],B=[3,2,1] ,即 棧 B 元素實現棧 A 元素倒序 。
利用棧 B 刪除隊首元素: 倒序後,B 執行出棧則相當於刪除了 A 的棧底元素,即對應隊首元素。


函數設計:
題目只要求實現 加入隊尾appendTail() 和 刪除隊首deleteHead() 兩個函數的正常工作,因此我們可以設計棧 A 用於加入隊尾操作,棧 B 用於將元素倒序,從而實現刪除隊首元素。

加入隊尾 appendTail()函數: 將數字 val 加入棧 A 即可。
刪除隊首deleteHead()函數: 有以下三種情況。
當棧 B 不爲空: B中仍有已完成倒序的元素,因此直接返回 B 的棧頂元素。
否則,當 A 爲空: 即兩個棧都爲空,無元素,因此返回 -1 。
否則: 將棧 A 元素全部轉移至棧 B 中,實現元素倒序,並返回棧 B 的棧頂元素。

 

複雜度分析:
由於問題特殊,以下分析僅滿足添加 N 個元素並刪除 N 個元素,即棧初始和結束狀態下都爲空的情況。

時間複雜度: appendTail()函數爲 O(1);deleteHead() 函數在 N 次隊首元素刪除操作中總共需完成 N 個元素的倒序。
空間複雜度 O(N) : 最差情況下,棧 A 和 B 共保存 N 個元素。

代碼

class CQueue {
    stack<int> st1;
    stack<int> st2;
public:
    CQueue() {
        
    }
    
    void appendTail(int value) {
        st1.push(value);
    }
    
    int deleteHead() {
        int res = -1;
        if (st1.empty() && st2.empty()) {
            return res;
        }
        if (st2.empty()) {
            while (!st1.empty()) {
                st2.push(st1.top());
                st1.pop();
            }
        }
        res = st2.top();
        st2.pop();  
        return res;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章