1 题1——20. 有效的括号
简单的栈的应用。自己写的AC版本:
由于栈结构的特殊性,非常适合做对称匹配类的题目。
class Solution {
public:
bool isValid(string s)
{
stack<char> sta;
for(int i = 0; i <s.size();i++)
{
if(s[i] == '(' || s[i] == '[' || s[i] == '{')
sta.push(s[i]);
else
{
if(!sta.empty())
{
char top = sta.top();
if(top == '(' && s[i] == ')')
{sta.pop();}
else if(top == '[' && s[i] == ']')
{sta.pop();}
else if(top == '{' && s[i] == '}')
{sta.pop();}
else return 0;
}else
return 0;
}
}
if(sta.empty())return 1;
else return 0;
}
};
2 题2——1047. 删除字符串中的所有相邻重复项
还是栈的应用。ac代码:
class Solution {
public:
string removeDuplicates(string s)
{
stack<char> sta;
for(int i = 0; i < s.size();i++)
{
if(sta.empty())sta.push(s[i]);
else if(sta.top() == s[i])sta.pop();
else sta.push(s[i]);
}
stack<char> tmp;
while(!sta.empty())
{
tmp.push(sta.top());
sta.pop();
}
string res = "";
string u = " ";
while(!tmp.empty())
{
u[0] = tmp.top();
res += u;
tmp.pop();
}
return res;
}
};
3 题3——150. 逆波兰表达式求值
在数据结构课中学过逆波兰表达式(又叫,RPN)(又叫,后缀表达式),所以用规则——“逆波兰表达式:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中”即可。
小坑:【1】需要特判负数【2】语法!!switch的括号里只能判断整数,所以干脆用 if - else 【3】当遇到符号时候,出来的两个数,第一个数应该是在符号的右边,作为表达式。
AC代码:
class Solution {
public:
int evalRPN(vector<string>& tokens)
{
// 逆波兰表达式:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中
stack<int> sta;
for(int i = 0; i < tokens.size();i++)
{
if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/" ) //是个数
{
// 需要特判负数
int flag = 0;
if(tokens[i][0] == '-') //负数
flag = 1;
int a = 0;
for(int j = 0 + flag; j < tokens[i].size();j++)
{
a *= 10;
a += tokens[i][j] - '0';
}
if(flag)a *= -1;
sta.push(a);
}
else // 不是数
{
int f1 = sta.top();
sta.pop();
int f2 = sta.top();
sta.pop();
int ans1 = 0;
//语法!!switch的括号里只能判断整数
if(tokens[i] == "+")ans1 = f1 + f2;
else if(tokens[i] == "-")ans1 = f2 - f1;
else if(tokens[i] == "*")ans1 = f1 * f2;
else if(tokens[i] == "/")ans1 = f2 / f1;
// cout << ans1 << endl;
sta.push(ans1);
}
}
return sta.top();
}
};
Carl知识点:
【1】只要知道逆波兰表达式是用后序遍历的方式把二叉树序列化了,就可以了。
【2】栈与递归之间在某种程度上是可以转换的!
总结:
1. 这节是栈的应用。用时:近2h。
2.无 todo