20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
思路:
for循环遍历查找对应括号
看完代码随想录之后的思路:
使用栈,这样可以同时解决数量和顺序的问题
遇到的非法情况无非三种:左边括号多了,右边括号多了,括号不多不少但是不匹配
class Solution {
public:
bool isValid(string s) {
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('}');
else if(st.empty()||st.top()!=s[i])return false;
//右括号多了,括号不多不少却不匹配
else st.pop();
}
return st.empty();//左边括号多了
}
};
遇到的困难:
else if(st.empty()||st.top()!=s[i])return false;
这一句中,需要西安判断是否为空,否则,如果是空栈却取了top,会报非法错误
收获:
if……else if 的条件集合是可以互相转化的,所以先写执行类型少的集合,最后else写执行类型多的集合
判断栈的top()元素时,一定先判断是否为empty()
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
思路:
栈
看完代码随想录之后的思路:
使用栈,但是需要使用一个字符串来保存pop的结果
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for(int i=0;i<s.size();i++)
{
if(st.empty()||st.top()!=s[i])st.push(s[i]);
else st.pop();
}
string result="";
while(!st.empty())
{
result+=st.top();
st.pop();
}
reverse(result.begin(),result.end());
return result;
}
};
或者直接将一个字符串当做栈,从backpush进去,这样最后留下来的直接可以输出
class Solution {
public:
string removeDuplicates(string S) {
string result;
for(char s : S) {
if(result.empty() || result.back() != s) {
result.push_back(s);
}
else {
result.pop_back();
}
}
return result;
}
};
收获:
在C++中,用单引号' '定义的是字符(char)类型,用双引号" "定义的是字符串(string)类型。
需要注意的是,如果在单引号中间包含多个字符,编译器会报错。如果单引号中间没有字符,编译器也会报错。
字符串的拼接可以直接使用+=
for(s:S)这种写法,不需要加索引,但是普通的for循环需要加索引
递归的返回也是用栈,但是大项目尽量不要用递归,更容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)
栈的适用类型:特别适合做相邻元素的特殊判断,例如相邻括号匹配,相邻字符消除
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);
else if(tokens[i]=="-")st.push(num2-num1);
else if(tokens[i]=="*")st.push(num2*num1);
else if(tokens[i]=="/")st.push(num2/num1);
}
else st.push(stoll(tokens[i]));
}
long long result=st.top();
st.pop();
return result;
}
};
遇到的困难:
vector<string> 类型的数据表示一个字符串数组,每个元素都是一个字符串,而字符串需要使用双引号 " " 表示,而不能使用单引号 ' '。定义如下:std::vector<std::string> words = {"hello", "world"};
后缀表达式,所以是使用后出栈做被算数,先出栈做算数:num2/num1
stoll 是 C++ 中的一个函数,用于将字符串转换为长整型数(long long 类型)。
std::string str = "1234567890";
long long num = std::stoll(str);
文章介绍了使用栈解决C++编程中的三个问题:检查有效括号字符串,删除字符串中的相邻重复项以及计算逆波兰表达式。通过栈,可以有效地处理括号匹配,消除相邻重复字符以及执行后缀表达式的计算。每个问题都提供了相应的C++代码实现。
533

被折叠的 条评论
为什么被折叠?



