【代码随想录算法训练营第十一天|20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值】

代码随想录算法训练营第十一天|20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

  • 1047. 删除字符串中的所有相邻重复项
  • 150. 逆波兰表达式求值

本博客代码来自于y总:https://www.acwing.com

#20. 有效的括号
我是一看就会,一写就费同学,关于有效括号这道题,我想介绍一套思路两套代码:
代码一:

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        unordered_map<char,char> hash = {{')','('},{']','['},{'}','{'}};
        for(int i = 0;i < s.size();i++)
        {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{') st.push(s[i]);
            else
            {
                //cout << st.top() - s[i] << endl;
                if(st.size() && st.top() == hash[s[i]]) st.pop();
                else return false;
            } 
        }
        return st.empty();
    }
};

代码二:

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for(int i = 0;i < s.size();i++)
        {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{') st.push(s[i]);
            else
            {
                //cout << st.top() - s[i] << endl;
                if(st.size() && abs(st.top() - s[i]) <= 2) st.pop();
                else return false;
            } 
        }
        return st.empty();
    }
};

首先,对于整体的思路就是,首先是要用到栈这个数据结构,然后思路就是遇到左括号就进栈,遇到右括号就查看栈顶元素的左括号和右括号是否匹配,如果匹配就弹栈,如果不匹配就返回fase。
这里我给出了两套代码,第一套是比较直接的查看左右括号的匹配,这里使用了map容器,然后第二套更为巧妙,因为这里使用了括号的ASCII码,通过查看ASCII码表得知,题目中列出的每种括号对的ASCII码差值不超过2,所以这里有一个<=2,但是还有一个问题,<=2可不止成对的括号,比如:"[“的ASCII码是91,”}"的ASCII码表是125,91 - 125 = -34,这个也<=2,当让然不能让它弹栈,所以要加一个abs()。

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

看代码:

class Solution {
public:
    string removeDuplicates(string s) {
        string res;
        for(auto c:s)
        {
            if(res.size() && res.back() == c) res.pop_back();
            else res += c;
        }
        return res;
    }
};

这道题目思路我想很多人是知道的,甚至都能想到用栈做,但是代码如何写呢?这里我不得不佩服y总的代码,简洁明了。
我一开始想全部压栈然后从后往前去合并,但是这个想法正确,代码不好写,尤其是字符串,如何删除第一个元素,如果是一个元素一个元素的往前移动,未必太慢了,还是y总有办法。
用一个string当作栈,也是最后的返回值,既然原字符串从头往后删删不动,那就用新字符串从后往前删,这样才行。

150. 逆波兰表达式求值

先看代码:

class Solution {
public:
    stack<int> stk;
    void eval(string s)
    {
        int b = stk.top();stk.pop();
        int a = stk.top();stk.pop();
        if(s == "+") stk.push(a + b);
        if(s == "-") stk.push(a - b);
        if(s == "/") stk.push(a / b);
        if(s == "*") stk.push(a * b);
    }
    int evalRPN(vector<string>& tokens) {
        unordered_set<string> S{"+","-","*","/"};
        for(auto s:tokens)
        {
            if(S.count(s)) eval(s);
            else stk.push(stoi(s));
        }
        return stk.top();
    }
};

这道题目很多人应该也不陌生,学栈的时候必须会接触到的,这里我想说的是字符转整的问题,这道题目一个障碍就是,原字符串中的1234都是字符串,要将字符串转化为int,所以要用stoi(),还有就是+ - * /,也是字符串,但是这个没办法转,那就用if。
最后总结一个字符(注意:这里说的是字符,不是字符串,字符是单引号,字符串是双引号)转数字的方法:比如’1’ - ‘0’ =1。

你可能感兴趣的:(算法,哈希算法)