由于栈结构的特殊性,非常适合做对称匹配类的题目。
20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
class Solution {
public:
bool isValid(string s) {
//如果s的长度是单数,则不是有效字符串,返回false
if(s.size()%2!=0) return false;
//定义一个栈,用来做字符串匹配
//有效的子字符串是对称的,符合先进后出的结构
stack<char> st;
for(int i=0;i<s.size();i++)
{
//读取到左括号,则将右括号写入栈
if(s[i]=='(') st.push(')');
else if(s[i]=='[') st.push(']');
else if(s[i]=='{') st.push('}');
//如果栈为空,或者栈顶元素不等于当前的元素,则返回false
else if(st.empty() || st.top()!= s[i]) return false;
//如果栈顶元素和当前元素一样,则弹出栈顶元素
else st.pop();
}
//empty() 用来判断队列是否为空,即是否没有元素。
//队列为空时,返回值为 1 (true);
//队列不为空时,返回值为 0 (false)。
return st.empty();
}
};
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
解法一:
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
// for(int i=0;i<s.size();i++)
// {
// char temp=s[i];
// }
for(char temp : s)
{
//如果栈为空,或者栈顶元素不等于当前元素,则写入当前元素
if(st.empty() || temp != st.top())
{
st.push(temp);
}
//如果当前元素与栈顶元素一样,则弹出栈顶元素
else st.pop();
//最后栈中剩下的元素,就是不重复的元素
}
//定义一个空字符串作为结果
string result="";
//如果栈中元素非空,则将栈中元素写入字符串中,同时弹出栈顶元素
while(!st.empty())
{
result+=st.top();
st.pop();
}
//原字符串“ca”,写入栈“ca”,弹出栈则变成“ac”,所以需要翻转字符串
reverse(result.begin(),result.end());
return result;
}
};
解法二:直接用字符串作为栈,减少了栈转为字符串的操作
class Solution {
public:
string removeDuplicates(string s) {
//直接用新字符串作为栈
string result;
for(char temp : s) {
//如果新字符串为空 或者新字符串的最后一个元素不等于当前元素
//则将当前元素写入新字符串
if(result.empty() || result.back() != temp) {
result.push_back(temp);
}
//如果当前元素等于新字符串最后一个元素,则弹出最后一个元素
else {
result.pop_back();
}
}
//直接返回新字符串
return result;
}
};
150. 逆波兰表达式求值
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 '+'、'-'、'*' 和 '/' 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用 32 位 整数表示。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
//逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。
//逆波兰表达式总是计算运算符前的两个元素
stack<long long> st;
for(int i=0;i<tokens.size();i++)
{
//如果当前的元素等于运算符时,则获取栈顶的两个元素,对他们进行运算,并再次写入栈顶
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/")
{
long long num1=st.top();
st.pop();
long long num2=st.top();
st.pop();
if(tokens[i]=="+") st.push(num2+num1);
if(tokens[i]=="-") st.push(num2-num1);
if(tokens[i]=="*") st.push(num2*num1);
if(tokens[i]=="/") st.push(num2/num1);
}
//如果不是操作符,则将运算对象写入栈顶
else
{
//stoll是将字符串类型转为long long类型
st.push(stoll(tokens[i]));
}
}
//返回栈中的最后一个元素
int result=st.top();
return result;
}
};