20.有效括号
题目: 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
链接: https://leetcode.cn/problems/valid-parentheses
思路: 遍历字符串,遇到左括号的时候把右括号放入栈里,遇到右括号的时候判断是不是和栈顶元素相匹配,如果匹配就弹出,不匹配(情况3)就返回false,最后看栈里是否有剩余元素(情况1);字符串尚未遍历完,栈已经为空(情况2)。
三种不匹配的情况:
- 有左括号找不到右括号,例如:
([{}]()
- 有右括号找不到左括号,例如:
[{}]())))
- 左右括号不匹配,例如:
[{(}}]
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();
}
}
if(st.empty()){
return true;
}
else{
return false;
}
}
};
1047. 删除字符串中的所有相邻重复项
题目: 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
链接: https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string
思路: 使用一个栈存放遍历过的元素,每次遍历的时候都判断一下当前元素和栈顶元素是否一致,若一致就消除,若不一致就存入栈中继续遍历。
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for(int i = 0; i < s.size(); ++i){
if(st.empty() || s[i] != st.top()){
st.push(s[i]);
}
else{
st.pop();
}
}
string res = "";
while(!st.empty()){
res += st.top();
st.pop();
}
reverse(res.begin(), res.end());
return res;
}
};
150.逆波兰表达式求值
题目: 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用 32 位 整数表示。
逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:
去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
链接: https://leetcode.cn/problems/evaluate-reverse-polish-notation
思路: 如果把已知字符串用二叉树表示,我们正常看到的表达式是“左中右”的中序遍历表达式,波兰表达式就是一种“左右中”的后序遍历表达式。
遍历vector<string>
,遇到数字就推入栈中,遇到运算符就计算一下。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(int i = 0; i < tokens.size(); ++i){
if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
int temp1 = st.top();
st.pop();
int temp2 = st.top();
st.pop();
if(tokens[i] == "+"){
st.push(temp1 + temp2);
}
if(tokens[i] == "-"){
st.push(temp2 - temp1);
}
if(tokens[i] == "*"){
st.push(temp1 * temp2);
}
if(tokens[i] == "/"){
st.push(temp2 / temp1);
}
}
else{
st.push(stoi(tokens[i]));
}
}
return st.top();
}
};