算法训练1-day9-栈与队列

35 阅读2分钟

今天的四道题是栈与队列

  1. 232. 用栈实现队列

用两个栈,一个栈inStack保存入队数据,另外一个栈outStack保存出队数据,通过两次后进先出达成先进先出:入队就将数据加入inStack;出队就从outStack弹出,如果outStack为空,就将inStack的值全部加入到outStack中,此时outStack中的顺序就是正确的入队顺序。

AC代码:

class MyQueue {
public:
    MyQueue() {}

    void push(int x) { inStack.push(x); }

    int pop() {
        if (outStack.empty()) {
            while (!inStack.empty()) {
                outStack.push(inStack.top());
                inStack.pop();
            }
        }

        int val = outStack.top();
        outStack.pop();
        return val;
    }

    int peek() {
        if (outStack.empty()) {
            while (!inStack.empty()) {
                outStack.push(inStack.top());
                inStack.pop();
            }
        }

        return outStack.top();
    }

    bool empty() { return inStack.empty() && outStack.empty(); }

private:
    stack<int> inStack;
    stack<int> outStack;
};
  1. 225. 用队列实现栈

每次有元素入队,就将它前面的元素重复出队入队的操作,直到ta排在最前面。

AC代码:

class MyStack {
public:
    MyStack() {}

    void push(int x) {
        q.push(x);
        int n = q.size();
        for (int i = 0; i < n - 1; ++i) {
            q.push(q.front());
            q.pop();
        }
    }

    int pop() {
        int val = q.front();
        q.pop();
        return val;
    }

    int top() { return q.front(); }

    bool empty() { return q.empty(); }

private:
    queue<int> q;
};
  1. 20. 有效的括号

注意只有一个字符的情况,或者是s的长度为奇数的情况都不合法

可以将右括号入栈,这样就只需要比较栈顶字符与当前s[i]是否相等,比左括号入栈要简单一些。

AC代码:

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for (char c : s) {
            if (c == '(' || c == '[' || c == '{') {
                st.push(c);
            } else {
                if (st.empty()) return false;
                char prev = st.top();
                if (c == ')') {
                    if (prev != '(') return false;
                    else st.pop();
                } else if (c == ']') {
                    if (prev != '[') return false;
                    else st.pop();
                } else {
                    if (prev != '{') return false;
                    else st.pop();
                }
            }
        }
        return st.empty();
    }
};

class Solution {
public:
    bool isValid(string s) {
        if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
        stack<char> st;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '(') st.push(')');
            else if (s[i] == '{') st.push('}');
            else if (s[i] == '[') st.push(']');
            // 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
            // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
            else if (st.empty() || st.top() != s[i]) return false;
            else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
        }
        // 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
        return st.empty();
    }
};
  1. 1047. 删除字符串中的所有相邻重复项

string带有pop_back和push_back,不需要额外的栈

class Solution {
public:
    string removeDuplicates(string s) {
        if (s.size() <= 1)
            return s;
        string ans;
        stack<char> st;
        for (char c : s) {
            if (st.empty()) {
                st.push(c);
                continue;
            }

            if (c == st.top()) {
                st.pop();
            }
            else{
                st.push(c);
            }
        }

        while (!st.empty()) {
            ans = st.top() + ans;
            st.pop();
        }

        return ans;
    }
};

class Solution {
public:
    string removeDuplicates(string s) {
        string stk;
        for (char ch : s) {
            if (!stk.empty() && stk.back() == ch) {
                stk.pop_back();
            } else {
                stk.push_back(ch);
            }
        }
        return stk;
    }
};

链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/solutions/643955/shan-chu-zi-fu-chuan-zhong-de-suo-you-xi-4ohr/
来源:力扣(LeetCode)