20.有效的括号
分析:之前做过一次,但还是毫无思路,感觉想的很复杂,看了卡哥的视频突然茅塞顿开
思路:把三种括号的左边括号都加入栈,扫描到右边括号的时候判断栈顶是不是对应的左括号,不是则直接返回false,是则把栈顶弹出
class Solution {
public:
bool isValid(string s) {
//不满足的情况:1.左括号和右括号数量不匹配 2.左括号和右括号数量匹配,但是没有对齐
int n=s.size();
if(n%2!=0)
return false;
stack<char>mids;
int index=0;
for(int i=0;i<n;i++)
{
if(s[i]=='(' || s[i]=='[' || s[i]=='{')
{
mids.push(s[i]);
//cout<<mids.top()<<endl;
}
else
{
if(mids.size()==0)
return false;
//index++;
if(s[i]==']')
{
if(mids.top()=='[')
mids.pop();
else
return false;
}
else if(s[i]=='}')
{
if(mids.top()=='{')
{
mids.pop();
cout<<mids.size()<<endl;
}
else
return false;
}
else
{
if(mids.top()=='(')
mids.pop();
else
return false;
}
}
}
// if(index!=n/2)
// return false;
if(mids.size()!=0)
return false;
return true;
}
};
感觉代码比较冗余,晚上看下如何解决
二刷:
思路:利用栈的特性进行匹配
class Solution {
public:
bool isValid(string s) {
stack<char>st;
unordered_map<char,char>map;
map['{']='}';
map['(']=')';
map['[']=']';
for(int i=0;i<s.size();i++){
if(s[i]=='{' || s[i]=='[' || s[i]=='(') st.push(s[i]);//左符号
else{
if(st.empty() || s[i]!=map[st.top()]) return false;//栈空或者不匹配
else st.pop();//符号匹配
}
}
return st.empty();//符号肯定为空
}
};
1047.删除字符串中的所有相邻重复字符
思路:利用栈的特性进行操作
class Solution {
public:
string removeDuplicates(string s) {
string result;
for(int i=0;i<s.size();i++)
{
if(result.empty() || s[i]!=result.back())
{
result.push_back(s[i]);
}
else
{
result.pop_back();
}
}
return result;
}
};
二刷:
思路:栈的特性,相同时直接删除尾部;不同时直接加入
class Solution {
public:
string removeDuplicates(string s) {
string res;
for(int i=0;i<s.size();i++){
if(!res.empty() && s[i]==res.back()) res.pop_back();
else res.push_back(s[i]);
}
return res;
}
};
150.逆波兰表达式
思路:使用栈的特性,在遍历到操作符时取出两个元素,然后进行操作
问题:刚开始我只取出了一个元素,然后把st.top()和这个被取出的元素运算,但是出现了问题,后来把两个都取出来解决了
class Solution {
public:
int evalRPN(vector<string>& tokens) {
int n=tokens.size();
stack<int>st;
for(int i=0;i<n;i++)
{
if(tokens[i]=="+" || tokens[i]=="-" || tokens[i]=="*" || tokens[i]=="/")
{
int mid=st.top();
st.pop();
int mid1=st.top();
st.top();
st.pop();
if(tokens[i]=="+")
st.push(mid1+mid);
else if(tokens[i]=="-")
st.push(mid1-mid);
else if(tokens[i]=="*")
st.push(mid1*mid);
else if(tokens[i]=="/")
st.push(mid1/mid);
}
else
{
st.push(atoi(tokens[i].c_str()));
}
}
return st.top();
}
};
二刷:
思路:使用栈进行遍历字符串
- 遍历到符号时,弹出两个数字进行运算
- 遍历到数字时,使用stoi转换字符串压入栈
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int>st;
for(int i=0;i<tokens.size();i++){
string mid=tokens[i];
int s=0;
if(mid=="+" || mid=="-" || mid=="*" || mid=="/"){//遍历到符号
int b=st.top();//弹出两个数字
st.pop();
int a=st.top();
st.pop();
if(mid=="+") s=a+b;//数字按照符号进行运算
else if(mid=="-") s=a-b;
else if(mid=="*") s=a*b;
else s=a/b;
st.push(s);
}
else st.push(stoi(mid));//遍历到数字
}
return st.top();
}
};