前置知识
参见前文
20. 有效的括号
题目描述
LeetCode链接:https://leetcode.cn/problems/valid-parentheses/description/
解题思路
思路: 创建一个栈, 遍历字符串, 每次遇到左括号就入栈, 遇到右括号就弹出栈顶元素进行匹配
匹配失败返回false, 最后栈非空false, 否则true
代码
这里可以选择是在入栈的时候进行左右括号的转换, 还是在出栈检查的时候进行转化.
我这里是在出栈检查的时候进行了转化(写了一个change函数进行对比)
但是也可以在入栈的时候, 入栈相反的括号.
class Solution {
public:
char change(char c){
if(c==')')
return '(';
else if(c=='}')
return '{';
else if(c==']')
return '[';
return '`';
}
bool isValid(string s) {
stack<char> st;
for(char c : s){
if(c=='(' || c=='{' || c=='[')
st.push(c);
else if(st.empty() || st.top()!=change(c)){
return false;
}else{
st.pop();
}
}
if(!st.empty())
return false;
return true;
}
};
1047. 删除字符串中的所有相邻重复项
题目描述
LeetCode链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/
用队列解题
思路: 可以使用数组, 但是数组的erase操作复杂度实在太高
所以使用queue进行操作
class Solution {
public:
// void printQ(queue<char> q){
// while(!q.empty()){
// cout << ' ' << q.front() ;
// q.pop();
// }
// cout << endl;
// }
string removeDuplicates(string s) {
int size=s.size();
queue<char> q;
for(char c : s){
q.push(c);
}
bool flag=true;
while(flag){
// printQ(q);
flag = false;
size = q.size();
queue<char> tmpQ;
while(!q.empty()){
char tmp = q.front();
q.pop();
if(tmp==q.front()){
q.pop();
flag = true;
}else{
tmpQ.push(tmp);
}
}
swap(q,tmpQ);
}
string ans;
while(!q.empty()){
ans.push_back(q.front());
q.pop();
}
return ans;
}
};
用栈解题
反而是用queue超出时间限制, 学习题解后使用栈.
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for(char c : s){
if(st.empty() || c!=st.top()){
st.push(c);
}else{
st.pop();
}
}
string ans;
while(!st.empty()){
ans.push_back(st.top());
st.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
};
用新字符串代替栈
能不能直接用string ans达到stack的效果呢?
这样就不用最后还将栈转化为字符串
class Solution {
public:
string removeDuplicates(string s) {
string ans;
for(char c : s){
if(ans.size()==0 || c!=ans[ans.size()-1]){
ans.push_back(c);
}else{
// ans.erase(ans.size()-1);
ans.pop_back();
}
}
return ans;
}
};
150. 逆波兰表达式求值
题目描述
LeetCode链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/
解题思路
思路: 用栈解决
遇到数字就入栈, 遇到符号了就拿出栈顶的两个元素和那个符合进行计算, 结果再入栈
代码
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
for(string c : tokens){
if(c=="+" || c=="-" || c=="*" || c=="/"){
long long nums1, nums2;
nums2 = st.top();
st.pop();
nums1 = st.top();
st.pop();
if(c=="+")
st.push(nums1 + nums2);
else if(c=="-")
st.push(nums1 - nums2);
else if(c=="*")
st.push(nums1 * nums2);
else if(c=="/")
st.push(nums1 / nums2);
}else{
st.push(stoll(c));
}
}
return st.top();
}
};
总结
什么时候使用栈?
总结这些题型可以发现: 在需要以特定的规律和顺序进行反复比较和存取操作的时候, 用栈会更方便.