「程式碼隨想錄演算法訓練營」第九天 | 棧與佇列 part1

云雀AC了一整天發表於2024-07-12

232. 用棧實現佇列

題目連結:https://leetcode.cn/problems/implement-queue-using-stacks/
題目難度:簡單
文章講解:https://programmercarl.com/0232.用棧實現佇列.html
影片講解:https://www.bilibili.com/video/BV1nY4y1w7VC
題目狀態:看影片講解後透過

思路:
透過兩個棧來實現佇列。

  • 建立兩個棧stackInstackOut
  • 當入隊的時候,直接把元素入stackIn棧中即可;
  • 當出隊的時候,若stackOut中沒有元素時,先將stackIn中的元素入stackOut中,再從stackOut中出棧;
  • 當返回隊頭時,直接呼叫出隊的程式碼即可;
  • 當判斷是否為空隊的時候,只需要判斷兩個棧是否都為空即可。

程式碼實現:

class MyQueue {
public:
    stack<int> stackIn;
    stack<int> stackOut;
    MyQueue() {

    }
    
    void push(int x) {
        stackIn.push(x);
    }
    
    int pop() {
        if(stackOut.empty()) {
            while(!stackIn.empty()) {
                stackOut.push(stackIn.top());
                stackIn.pop();
            }
        }
        int res = stackOut.top();
        stackOut.pop();
        return res;
    }
    
    int peek() {
        int res = this->pop();
        stackOut.push(res);
        return res;
    }
    
    bool empty() {
        return stackIn.empty() && stackOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

225. 用佇列實現棧

題目連結:https://leetcode.cn/problems/implement-stack-using-queues/
題目難度:簡單
文章講解:https://programmercarl.com/0225.用佇列實現棧.html
影片講解:https://www.bilibili.com/video/BV1Fd4y1K7sm
題目狀態:看程式碼隨想錄思路後透過

思路一(兩個佇列):

  • 建立兩個佇列,一個是用來各種操作的佇列que1,一個用來儲存元素的輔助佇列que2
  • 入棧:將元素壓入que1中即可;
  • 出棧:將que1中除了最後一個元素以外的其他元素壓入que2中,並將que1中的最後一個元素輸出,最後將que2中的元素再返給que1並清空que2
  • 輸出棧頭:返回que1的隊尾;
  • 判斷棧是否為空:返回que1佇列是否為空。

程式碼實現:

class MyStack {
public:
    queue<int> que1;
    queue<int> que2;
    MyStack() {

    }
    
    void push(int x) {
        que1.push(x);
    }
    
    int pop() {
        int size = que1.size();
        size--;
        while(size--) {
            que2.push(que1.front());
            que1.pop();
        }
        int res = que1.front();
        que1.pop();
        que1 = que2;
        while(!que2.empty()) {
            que2.pop();
        }
        return res;
    }
    
    int top() {
        return que1.back();
    }
    
    bool empty() {
        return que1.empty();
    }
};

/**
 * 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();
 * bool param_4 = obj->empty();
 */

思路二(一個佇列)

  • 建立一個佇列que
  • 入棧:將元素壓入que中即可;
  • 出棧:將que中除了最後一個元素以外的其他元素重新壓入que中,並將que剛開始的最後一個元素(現在是第一個元素)彈出;
  • 輸出棧頭:返回que的隊尾;
  • 判斷棧是否為空:返回que佇列是否為空。

程式碼實現:

class MyStack {
public:
    queue<int> que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);
    }
    
    int pop() {
        int size = que.size();
        size--;
        while(size--) {
            que.push(que.front());
            que.pop();
        }
        int res = que.front();
        que.pop();
        return res;
    }
    
    int top() {
        return que.back();
    }
    
    bool empty() {
        return que.empty();
    }
};

/**
 * 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();
 * bool param_4 = obj->empty();
 */

20. 有效的括號

題目連結:https://leetcode.cn/problems/valid-parentheses/
題目難度:簡單
文章講解:https://programmercarl.com/0020.有效的括號.html
影片講解:https://www.bilibili.com/video/BV1AF411w78g
題目狀態:看程式碼隨想錄思路後透過

思路:

  • 若字串中元素的個數為奇數,說明括號肯定不匹配,直接返回false
  • 建立一個棧;
  • 如果遍歷的元素是括號的左半部分,將對應的右半部分壓入到棧中;
  • 如果遍歷到的元素是括號的右半部分,則判斷棧中的元素是否和該括號對應,若不對應,說明兩個括號無法匹配,則返回false
  • 若棧中元素和遍歷到的元素匹配且最終棧為空,則返回true

程式碼實現:

class Solution {
public:
    bool isValid(string s) {
        if(s.size() % 2 != 0) return false;
        stack<char> st;
        for(auto &sElem : s) {
            if(sElem == '(') st.push(')');
            else if(sElem == '{') st.push('}');
            else if(sElem == '[') st.push(']');
            else if(st.empty() || st.top() != sElem) return false;
            else st.pop();
        }
        return st.empty();
    }
};

1047. 刪除字串中的所有相鄰重複項

題目連結:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/
題目難度:簡單
文章講解:https://programmercarl.com/1047.刪除字串中的所有相鄰重複項.html
影片講解:https://www.bilibili.com/video/BV12a411P7mw
題目狀態:透過

個人思路:

  • 建立一個棧來存放字串中的元素;
  • 遍歷字串;
  • 若棧不為空且遍歷到的字串中的元素等於棧中的元素,將棧中元素彈出;
  • 相反,若遍歷到的元素不等於棧中的元素,則將元素壓入棧中;
  • 遍歷完成後,將棧中的元素依次彈出,並儲存在一個string型別的變數res中;
  • 反轉res並返回。

程式碼實現:

class Solution {
public:
    string removeDuplicates(string s) {
        int size = s.size();
        stack<char> st;
        for(auto &sElem : s) {
            if(!st.empty() && sElem == st.top()) st.pop();
            else st.push(sElem);
        }
        string res;
        while(!st.empty()) {
            res += st.top();
            st.pop();
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

相關文章