day11 | 栈的应用

77 阅读1分钟

20. 有效的括号

题目链接:leetcode.cn/problems/va…

要点

  • 不匹配的三种情况:左括号多了、右括号多了、对应括号不匹配
  • 对每次遍历到某个字符,可进行的操作:
    1. 是左括号,入栈
    1. 右括号,看是否匹配
    1. 栈已空,缺少左括号
    1. 字符串遍历结束,栈非空,左括号多了

括号匹配

class Solution {
public:
    bool isValid(string 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(']');
            //两种返回false的情况如下
            else if (st.empty() || s[i] != st.top()) return false;
            else st.pop();
        }

        //第三种返回false的情况
        return st.empty();
    }
};

总结

if的条件撇去入栈的操作就剩下返回false的操作和匹配时pop的操作,在遍历过程中,两种false的情况可以直接return,还有一种得遍历完才发现。

优化:最开始判断s.size()是否为奇数,若是就直接return.

1047. 删除字符串中的所有相邻重复项

题目链接:leetcode.cn/problems/re…

要点

  • string 不支持 push_front, emplace_front,只能从串尾追加字符或字符串
  • 头文件 “algorithm”的函数reverse(),参数为两个迭代器,翻转容器内的元素
  • stack, queue容器都不能用迭代器遍历

消消乐

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

总结

stack作消消乐,再将其中的元素转为string。也可以直接在string上作消消乐操作push_back, pop_back

150. 逆波兰表达式求值

题目链接:leetcode.cn/problems/ev…

要点

  • 逆波兰式相当于是二叉树的后序遍历,其中运算符为中间节点,数字为子节点。最先进行的运算在叶子节点
  • 本题的所有数字和中间结果都是32位整数内,不管是32位还是64位编译器,long都够用了
  • 在类中,如果什么都没有,则类占用1个字节;只有成员函数也是只占1字节
  • stol, stoll函数,字符串转long, long long

求值

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        for (int i = 0; i < tokens.size(); i++) {
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
                long long num1 = st.top();st.pop();
                long long num2 = st.top();st.pop();
                if (tokens[i] == "+") st.push(num1 + num2);
                if (tokens[i] == "-") st.push(num2 - num1);      //出bug
                if (tokens[i] == "*") st.push(num1 * num2);
                if (tokens[i] == "/") st.push(num2 / num1);      //出bug
            }else {
                st.push(stoll(tokens[i]));
            }
        }
        return st.top();
    }
};

总结

注意:st.top()出的num的运算顺序!