1.20个有效的括号
括号解决问题是一个比较经典的问题。
思路:字符匹配,根据新来的是不是和最近的那个是不是相匹配的方式来确定是否有效,这就和栈的思路很相匹配。
两种返回false的方式:
第一种就近(stack.top())的那个不相匹配。
第二种全部遍历完成之后,栈如果不为空,那么就是不匹配
匹配:全部遍历完成之后,栈为空。
class Solution {
public:
bool isValid(string s) {
stack<char> stack;
for(char ch:s){
if(ch=='('){
stack.push(ch);
}else if(ch == '['){
stack.push(ch);
}else if(ch == '{'){
stack.push(ch);
}else if(ch==')'){
if(stack.empty()||stack.top()!='('){
return false;
}else{
stack.pop();
}
}else if(ch == ']'){
if(stack.empty()||stack.top()!='['){
return false;
}else{
stack.pop();
}
}else if(ch == '}'){
if(stack.empty()||stack.top()!='{'){
return false;
}else{
stack.pop();
}
}
}
return stack.empty();
}
};
2.1047删除字符串中的所有相邻重复项
思路:使用栈来进行判断是否重复。
入栈的方式:该栈为空或该栈的顶不等于当前遍历的值。
出栈的方式:如果该栈的顶等于当前的遍历的值。
最后的栈里面存放的就是不相邻的重复项,最后遍历放到string中即可。
class Solution {
public:
string removeDuplicates(string s) {
//好像可以直接使用string t;使用t.push_back()这样的方法
stack<char> stack;
for(char ch:s){
if(stack.empty()||stack.top()!=ch){
stack.push(ch);
}else{
stack.pop();
}
/*
if(s[i]==s[i-1]){
s.erase(s[i]);
i = i-2;
n--;
}*/
}
int n = stack.size();
int i = n-1;
while(!stack.empty()){
s[i--] = stack.top();
stack.pop();
}
s.resize(n);
return s;
}
};
3.150逆波兰表达式求值
思路:栈存放表达式的值。在遍历的过程中如果遇到了运算符,将栈上面的两个元素取出,计算出此时的表达式的值,再存入栈。如果遇到了数字,直接存入栈即可。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> stack;
for(string s:tokens){
if(s=="+"){
int s1 = stack.top();
stack.pop();
int s2 = stack.top();
stack.pop();
s2 += s1;
stack.push(s2);
}else if(s == "-"){
int s1 = stack.top();
stack.pop();
int s2 = stack.top();
stack.pop();
s2 -= s1;
stack.push(s2);
}else if(s == "*"){
int s1 = stack.top();
stack.pop();
int s2 = stack.top();
stack.pop();
s2 *= s1;
stack.push(s2);
}else if(s == "/"){
int s1 = stack.top();
stack.pop();
int s2 = stack.top();
stack.pop();
s2 /= s1;
stack.push(s2);
}else{
int num = 0;
int flag = 1;
for(char ch:s){
if(ch =='-'){
flag = -1;
}else{
num = num*10+ch-'0';
}
}
stack.push(num*flag);
}
}
return stack.top();
}
};