代码随想录算法训练营day10|20 有效的括号 1047 删除字符串中的所有相邻重复项 150 逆波兰表达式求值
LeetCode 20 有效的括号
题目链接: 20.有效的括号
class Solution{
public:
bool isValid(string s) { //利用栈的思想解决问题
if(s.size() % 2) //如果s数量不为偶数,肯定无法匹配
return false;
stack<char> st;
for(char a : s) {
//先将三种左括号对应的右括号入栈
if(a == '(')
st.push(')');
else if(a == '[')
st.push(']');
else if(a == '{')
st.push('}');
//判断右括号的数量是否过多或者右括号不匹配
else if(st.empty() || st.top() != a)
return false;
//括号匹配
else
st.pop();
}
return st.empty();
}
};
本题小结:本题需要理清可能会出现的所有情况:左括号不匹配、左括号过多、右括号过多,分情况考虑即可。
LeetCode 1047 删除字符串中的所有相邻重复项
题目链接: 1047.删除字符串中的所有相邻重复项
class Solution {
public:
string removeDuplicates(string S) {
stack<char> st;
for(int i = 0; i < S.size(); i++) {
if(st.empty() || st.top() != S[i]) { //当且仅当栈为空或者栈顶元素不等于遍历元素时
st.push(S[i]);
}
else { //删除重复字符
st.pop();
}
}
//存放新字符
string res;
while(!st.empty()) {
res += st.top();
st.pop();
}
//由于栈的出栈特性,需要将字符顺序反转
reverse(res.begin(), res.end());
return res;
}
};
也可以将字符串直接作为栈进行操作
class Solution {
public:
string removeDuplicates(string S) {
string res;
for(char s:S) {
if(res.empty() || res.back() != s) {
res.push_back(s);
}
else {
res.pop_back();
}
}
return res;
}
};
本题小结:首先想到用栈来进行消除,但是基于字符串的特殊性,也可以将字符串直接作为栈,更为方便。
LeetCode 150 逆波兰表达式求值
题目链接: 150.逆波兰表达式求值
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 a = st.top();
st.pop();
int 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(stoi(tokens[i]));
}
return st.top();
}
};
本题小结:由于逆波兰表达式是运算符中缀表现形式,用栈解决,思想为遇到数字字符就入栈,遇到运算字符就将栈顶两个元素进行计算,并将计算结果继续入栈。