目录
a.20. 有效的括号
b.1047. 删除字符串中的所有相邻重复项
c.150. 逆波兰表达式求值
a.20. 有效的括号
题目链接
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()" 输出:true
示例 2:
输入:s = "()[]{}" 输出:true
示例 3:
输入:s = "(]" 输出:false
思路:由于栈结构的特殊性,非常适合做对称匹配类的题目。这里考虑用栈做匹配,一般思路是遇到左括号入栈,遇到匹配的右括号弹出栈顶元素,也可以遇到左括号则相应右括号入栈,遇到右括号,比较栈顶元素与右括号是否相同,相同则弹出
class Solution {
public:bool isValid(string s) {if((s.size()%2)!=0)return false; //如果括号总数不是偶数,必然有多余括号没匹配上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('}');}else if(st.empty()|| s[i]!=st.top()) return false;else st.pop();}return st.empty();}
};
b.1047. 删除字符串中的所有相邻重复项
题目链接
给出由小写字母组成的字符串 S
,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca" 输出:"ca" 解释: 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
思路:比较栈顶元素,遇到相同元素则弹出栈顶元素,继续比较下一个元素;遇到不同元素,入栈,最后栈留存元素就是删除重复字母后的结果字符串(当然,得反转一下)
class Solution {
public:string removeDuplicates(string s) {if(s.size()<=1)return s;stack<char>st;st.push(s[0]);for(int i=1;i<s.size();i++){if((!st.empty())&&st.top()==s[i]) st.pop();else st.push(s[i]);}string result="";while(!st.empty()){result+=st.top();st.pop();}reverse(result.begin(),result.end());return result;}
};
c.150. 逆波兰表达式求值
题目链接
给你一个字符串数组 tokens
,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为
'+'
、'-'
、'*'
和'/'
。 - 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
示例 1:
输入:tokens = ["2","1","+","3","*"] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = ["4","13","5","/","+"] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"] 输出:22 解释:该算式转化为常见的中缀算术表达式为:((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22
思路:遇到运算符,取出栈里的两个元素,然后进行运算;否则将元素压入栈,注意tokens里的元素是字符串,需要转换一下类型
class Solution {
public:int evalRPN(std::vector<std::string>& tokens) {std::stack<long long> st;for (int i = 0; i < tokens.size(); i++) {if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {long long a = st.top();st.pop();long long b = st.top();st.pop();if (tokens[i] == "+") st.push(b + a);if (tokens[i] == "-") st.push(b - a);if (tokens[i] == "*") st.push(b * a);if (tokens[i] == "/") st.push(b / a);} else {st.push(stoll(tokens[i]));}}int result = st.top();st.pop();return result;}
};