【每日一題】LeetCode. 劍指Offer 09. 用兩個棧實現隊列

每日一題,防止癡呆 = =

一、題目大意

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,deleteHead 操作返回 -1 )
在這裏插入圖片描述
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof

二、題目思路以及AC代碼

思路:

這道題我一開始看到的時候第一思路是這樣的:因爲讓用兩個棧來實現隊列,我們只需要一個棧來存儲元素,另一個棧在輸出時用來顛倒一下就可以了,我覺得這也是最暴力的辦法了,然後時間花費的有一些多,我就考慮如何更簡便的去做。

上面的做法是每次在輸出元素的時候,都要對存儲數據的棧做一次顛倒,這着實沒有什麼必要,因爲我們如果先連續的向隊列裏push,再連續的從隊列裏取出,其實我們只要顛倒一次,然後不斷的從顛倒的棧中取出即可,這樣我們可以針對連續push和連續pop的情況進行優化,即我們只在push和pop操作交替的時候,才進行顛倒的操作,這樣應該就可以減少很多時間消耗,結果表明,確實效果更好的一些,但還不是很明顯。

然後我參考了一下速度快一些的代碼的思路,他們和我一樣是使用兩個數組,一個用來append,一個用來delete,但是在append的時候不做操作,直接append到第一個棧中,然後在輸出元素,也就是delete的時候,如果第二個棧不爲空,則直接delete,如果爲空,那麼把第一個棧中的元素顛倒順序保存到第二個棧中,繼續。這種方法看起來好像是包含了上面的優化方法的。

AC代碼

最暴力:

class CQueue {
private:
    stack<int> content;
public:
    CQueue() {

    }
    
    void appendTail(int value) {
        content.push(value);
    }
    
    int deleteHead() {
        if (content.empty()) return -1;

        stack<int> temp;
        while (!content.empty()) {
            temp.push(content.top()); content.pop();
        }
        int res = temp.top(); temp.pop();
        while (!temp.empty()) {
            content.push(temp.top()); temp.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();
 */

只在操作交替時顛倒:

class CQueue {
private:
    stack<int> append_stack;
    stack<int> delete_stack;
    bool appending;
public:
    CQueue() {
        appending = true;
    }
    
    void appendTail(int value) {
        if (!appending) {
            // while (!append_stack.empty()) append_stack.pop();
            appending = true;
            while(!delete_stack.empty()) {
                append_stack.push(delete_stack.top()); delete_stack.pop();
            }
        }
        append_stack.push(value);
    }
    
    int deleteHead() {
        if (appending) {
            // while (!delete_stack.empty()) delete_stack.pop();
            appending = false;
            while (!append_stack.empty()) {
                delete_stack.push(append_stack.top()); append_stack.pop();
            }
        }
        if (delete_stack.empty()) return -1;
        int res = delete_stack.top(); delete_stack.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();
 */

只在需要時顛倒:

class CQueue {
private:
    stack<int> append_stack;
    stack<int> delete_stack;
public:
    CQueue() {
        
    }
    
    void appendTail(int value) {
        append_stack.push(value);
    }
    
    int deleteHead() {
        int res = -1;
        if (!delete_stack.empty()) {
            res = delete_stack.top(); delete_stack.pop();
            return res;
        }
        while (!append_stack.empty()) {
            delete_stack.push(append_stack.top()); append_stack.pop();
        }
        if (!delete_stack.empty()) {
            res = delete_stack.top(); delete_stack.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();
 */

如果有問題,歡迎大家指正!!!

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