20. 有效的括号
代码
class Solution { public: bool isValid(string s) { stack<char>s_s; //返回条件: //1 遍历结束 栈不为空 返回false,因为符号与栈顶匹配的都被pop出了 //2 遍历途中栈为空,待插入字符为括号右边符号则直接返回false;一开始就是右边符号肯定是错误的 //3 遍历途中栈不为空,符号不等于栈顶值且是括号右边值则直接返回 false;同理等待插入的符号为符号左边那一定是错误的,因为括号位置左右反了。 for(int i = 0;i< s.size();++i){ char val = s[i]; if(!s_s.empty() && val==s_s.top()){ s_s.pop(); }else{ switch (val){ case '(' : s_s.push(')');break; case '[' : s_s.push(']');break; case '{' : s_s.push('}');break; default :return false; //栈为空且字符为括号右边,直接返回false; } } } return s_s.empty(); } };
思路
使用栈先入后出的属性可以实现,栈插入的字符全部是括号右边。
1 栈为空的情况下要插入的字符是左边括号则直接返回false;因为一开始的插入了左侧括号后面是无法在括号规则正确的情况下弹出括号的。如“)(”,遍历找到了‘)’则要插入的符号为‘(’,显然这是不可以的。
2 栈不为空的情况下栈顶值不等于当前遍历的字符,且字符为右边括号,直接返回false;因为栈顶值不等于当前被遍历的字符,则说明当前括号的右边括号是准备被插入的字符,如果括号本身已经是右边字符则无法插入,说明该括号是一个不配对的字符。如“{ } { ) }”‘{’插入的是‘}’,‘}’与栈顶值‘}’相等
所以pop掉,同样地,第三个字符‘{’要插入栈顶的是‘}’,‘)’不等于栈顶部值,则‘)’会被作为一个要插入栈顶的字符,但是如果插入了则后面就不会有右边字符与其匹配,所以不能插入,字符串括号不匹配。
3 遍历结束后栈为空则返回ture,否则返回false;
难点
上述三点一开始不太好想到。
总结
简单题。主要加深对栈的使用。
1047. 删除字符串中的所有相邻重复项
代码
class Solution { public: string removeDuplicates(string s) { string res; for(char val :s){ if(!res.empty() && val == res.back()){ res.pop_back(); }else{ res.push_back(val); } } return res; } };
思路
采用栈的思想,遍历字符,如果栈内的字符和当前字符相等则将其弹出,继续下一层遍历,直到所有字符都遍历完成,栈内剩下的字符就是不相邻的字符,将其反转就可以得到结果
难点
不难
总结
也是考察对栈的使用
150. 逆波兰表达式求值
代码
class Solution { public: int evalRPN(vector<string>& tokens) { stack<long long> number; for(string val : tokens){ if(val == "+"||val=="-"||val=="*"||val=="/"){ long long res1 = number.top(); number.pop(); long long res2 = number.top(); number.pop(); if(val == "+") number.push(res2 + res1); if(val == "-") number.push(res2 - res1); if(val == "*") number.push(res2 * res1); if(val == "/") number.push(res2 / res1); }else{ number.push(stoi(val)); } } return number.top(); } };
思路
遍历字符,将不等于+-*/的字符全部转换成数字存入站内,字符串的前面一定是数字字符。所以遍历到+-*/时就可以栈顶两个元素弹出,计算出结果后在插入栈顶,直到遍历结束,栈顶值就是逆波兰表达式的结果。
难点
要理解什么是逆波兰表达式。
总结
深入理解了栈这种数据结构。
参考来源
有效括号:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html