20.括号匹配
括号匹配是使用栈解决的经典问题。由于栈结构的特殊性,非常适合做对称匹配类的题目。
细节:①剪枝,奇数长度直接返回false;②分析各种可能出现的情况。
利用“配对”思想,从一开始向后遍历字符串检测到输入左括号的时候,直接push右括号。因为检测到输入右括号可以直接return false;
检测到右括号的时候,要一并判断一下当前栈是否是空的。
class Solution {
public:
bool isValid(string s) {
//剪枝:首先字符串不是偶数项的话,直接返回false;
int length = s.size();
if (length % 2 == 1){
return false;
}
stack<char> sss;
for (int i = 0; i<s.size(); i++){
if (s[i] == '(' ){
sss.push(')');
}
else if (s[i] == '['){
sss.push(']');
}
else if (s[i] == '{'){
sss.push('}');
}
else if (sss.empty() || s[i] != sss.top()){
// 在这里要加上判断栈是否是空的。空的直接返回false
return false;
}
else {
sss.pop();
}
}
return sss.empty();
}
};
1047.删除字符串中的所有相邻重复项
消消乐,遍历压入元素,判断后压入的是否一致,决定是否弹出;
carl的解法,有一种解法是将字符串作为栈直接操作。节省了一半的空间时间。
class Solution {
public:
string removeDuplicates(string s) {
stack<char> count;
for (int i = 0; i<s.size(); i++){
if (count.empty()){
count.push(s[i]);
continue;
}
if ( s[i] != count.top() ){
count.push(s[i]);
}
else {
count.pop();
}
}
string ans = ""; //初始化一个字符串的格式;
while (!count.empty()){
int j = 0;
ans += count.top();
count.pop();
}
if (ans != ""){
for (int i = 0, j = ans.size()-1; i<j; i++, j--){
swap(ans[i], ans[j]);
}
}
return ans;
}
};
150.逆波兰表达式求值
遍历tokens,检测到运算符号的时候,栈弹出两个数字来做运算。
没有检测到运算符号的时候,就日常将数字压入栈。
字符串转换代码:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
// 元素为字符串的vector;
stack<long long> ans;
for (int i = 0; i<tokens.size(); i++){
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
long long a = ans.top();
ans.pop();
long long b = ans.top();
ans.pop();
if (tokens[i] == "+"){
ans.push(a+b);
}
if (tokens[i] == "-"){
ans.push(b-a);
}
if (tokens[i] == "*"){
ans.push(a*b);
}
if (tokens[i] == "/"){
ans.push(b/a);
};
}
else {
ans.push(stoll(tokens[i]));
}
}
int result = ans.top();
ans.pop();
return result;
}
};