文档讲解:
20.有效的括号
题目链接:https://leetcode.cn/problems/valid-parentheses/
思路:
这题很简单,和最普通那版括号匹配是一个类型,只不过这里的括号类型有三种。
解决问题的方式很简单,碰到左括号就压入栈,碰到右括号就和栈顶判断,如果匹配就弹出栈顶,如果不匹配证明整个串不匹配。
核心代码:
class Solution {
public:
bool isValid(string s) {
stack<char> st;
int n=s.length();
bool flag=true;
for(int i=0;i<n;i++){
if(s[i]=='('||s[i]=='['||s[i]=='{') st.push(s[i]);
else{
if(st.empty()){
flag=false;
break;
}
char c=st.top();
st.pop();
if(c=='('&&s[i]==')') continue;
else if(c=='['&&s[i]==']') continue;
else if(c=='{'&&s[i]=='}') continue;
else{
flag=false;
break;
}
}
}
if(!st.empty()) flag=false;
return flag;
}
};
1047.删除字符串中的所有相邻重复项
题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/
思路:
这题也很简单,和上一道类似的做法。
我们每次读入一个字符,在压入栈之前先进行判断,如果和栈顶相同,证明重复,将栈顶弹出。如果不同,证明不重复,将其压入栈。
重复上述操作,最后保留在栈中的就是去掉相邻重复项的字符串,从栈中弹出输出即可。
当然,我们要注意到从栈中弹出的字符组成的字符串与原本顺序相反,不要忘记翻转一下。
核心代码:
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
int n=s.length();
for(int i=0;i<n;i++){
if(!st.empty()&&st.top()==s[i]) st.pop();
else st.push(s[i]);
}
s="";
while(!st.empty()){
s+=st.top();
st.pop();
}
n=s.length();
char c;
for(int i=0;i<n/2;i++){
c=s[i];
s[i]=s[n-1-i];
s[n-1-i]=c;
}
return s;
}
};
150.逆波兰表达式求值
题目链接:https://leetcode.cn/problems/valid-parentheses/
思路:
所谓的逆波兰表达式,简单来说就是说碰到运算符,就将其之前的两个数字进行该运算。那我们根据这个性质发现一个事实,取最近的数还是可以用栈来存储,因为我们的栈是后进先出。
所以我们用栈来存储数据。遇到数字就将其压入栈,遇到运算符就取出栈顶的两个元素进行该运算,然后再将值压回栈。
重复上述操作,最终栈里剩下的元素就是表达式的值。
核心代码:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
int n=tokens.size();
for(int i=0;i<n;i++){
string s=tokens[i];
if(s=="+"||s=="-"||s=="*"||s=="/"){
int a,b,num;
b=st.top();st.pop();
a=st.top();st.pop();
if(s=="+") num=a+b;
if(s=="-") num=a-b;
if(s=="*") num=a*b;
if(s=="/") num=a/b;
st.push(num);
}
else{
int num=0,t=1,j=0;
int ns=s.length();
if(s[0]=='-') t=-1,j=1;
while(j<ns){
num*=10;
num+=s[j]-'0';
j++;
}
num*=t;
st.push(num);
}
}
return st.top();
}
};
今日总结
今日学习时长2h,栈我已经很熟悉了,类似的题目做过很多了,所以没花什么时间。
依旧要复习周末期末考试。