20.有效的括号
有关匹配问题都是栈的强项,本题思路为:在遇到左括号时压栈,遇到右括号时弹出栈顶元素看是否匹配,注意处理栈空的边界条件即可
class Solution {
public:
bool isMatched(char a,char b){
if(a=='('&&b==')')
return 1;
if(a=='['&&b==']')
return 1;
if(a=='{'&&b=='}')
return 1;
else
return 0;
}
bool isValid(string s) {
stack<char> bracket;
//遇到左括号则压栈
for(int i=0;i<s.size();i++){
if(s[i]=='('||s[i]=='['||s[i]=='{'){
bracket.push(s[i]);
} else{
//在匹配完成前栈空说明右括号多了
if(bracket.empty())return false;
else if(!bracket.empty()){
char tmp=bracket.top();
bracket.pop();
if(!isMatched(tmp,s[i]))
return false;
}
}
}
//匹配结束后栈不空说明左括号多了
if(!bracket.empty())return false;
return true;
}
};
1047.删除字符串中所有相邻重复项
也算是“匹配”问题,将字符串中的字符添加进栈中,每添加新的元素时比较栈顶元素是否和要添加元素相同,若相同则“删除”这两个元素,最后在栈中的元素即为所求,但由于栈的先进后出的特性,出栈后得到的字符串需反转才是结果
class Solution {
public:
string removeDuplicates(string s) {
stack<char> res;
string ret;
int p=0;
while (p<s.size()){
if(res.empty())res.push(s[p]);
else
if(s[p]==res.top()){
res.pop();
} else{
res.push(s[p]);
}
p++;
}
while (!res.empty()){
ret+=res.top();
res.pop();
}
reverse(ret.begin(),ret.end());
return ret;
}
};
150.逆波兰式求值
就是后缀表达式求值,每遇到操作数就压栈,遇到运算符就弹出两个操作数运算再把结果压栈,直到遍历完表达式
class Solution {
public:
int operation(int a,int b,string s){
if(s=="+")return a+b;
if (s=="-")return a-b;
if(s=="*")return a*b;
return a/b;
}
int evalRPN(vector<string> &tokens) {
stack<int> s;
if(tokens.size()==1)return stoi(tokens[0]);
int res=0;
int tmp1;
int tmp2;
for (int i = 0; i < tokens.size(); ++i) {
if(tokens[i]=="+"||tokens[i]=="-"
||tokens[i]=="*"||tokens[i]=="/"){
tmp1=s.top();
s.pop();
tmp2=s.top();
s.pop();
res=operation(tmp2,tmp1,tokens[i]);
s.push(res);
} else{
s.push(stoi(tokens[i]));//转换成数字
}
}
return res;
}
};