代码随想录算法训练营day10 | 232.用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项
栈的常用接口:
stack
stk.push(10);
stk.pop();
stk.top() //返回栈顶元素的引用,可作为左值,也可作为右值
stk.empty() //判空
stk.size()
队列的常用接口:
queue
que.push(10);
que.pop();
que.front(); //返回队头元素
que.back(); //返回队尾元素
que.empty(); //判空
que.size();
232.用栈实现队列
点击查看代码
class MyQueue {
public:
MyQueue() {
}
void push(int x) {
while(!stk_2.empty()) {
stk_1.push(stk_2.top());
stk_2.pop();
}
stk_1.push(x);
while(!stk_1.empty()) {
stk_2.push(stk_1.top());
stk_1.pop();
}
}
int pop() {
int queFrontEle = stk_2.top();
stk_2.pop();
return queFrontEle;
}
int peek() {
return stk_2.top();
}
bool empty() {
return stk_2.empty();
}
private:
stack<int> stk_1; //辅助栈
stack<int> stk_2; //队列
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
使用两个栈模拟队列,第一个栈作为辅助栈,仅在队列push的时候使用,而第二个栈作为真正的队列,栈顶即是队头。
队列push时,先将栈2的所有元素依次导入栈1,然后新元素push进栈1,最后栈1所有元素导入栈2,则能使栈2保持队列形态。
225.用队列实现栈
解法一:两个队列模拟栈
点击查看代码
class MyStack {
public:
MyStack() {
}
void push(int x) {
while(!que_2.empty()) {
que_1.push(que_2.front());
que_2.pop();
}
que_2.push(x);
while(!que_1.empty()) {
que_2.push(que_1.front());
que_1.pop();
}
}
int pop() {
int stkTopEle = que_2.front();
que_2.pop();
return stkTopEle;
}
int top() {
return que_2.front();
}
bool empty() {
return que_2.empty();
}
private:
queue<int> que_1; //辅助队列
queue<int> que_2; //栈
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
使用两个队列模拟栈,本题思路与232.用栈实现队列基本一致,队列1作为辅助队列,仅在栈push时使用,队列2作为真正的栈,在栈push时,将队列2的所有元素依次导入队列1中,再将要入栈的元素push进队列2中,最后将队列1的所有元素重新导入队列2中,由此满足后入先出的特性。
本题亦可使用一个队列模拟栈,但需要额外定义队列中当前元素个数size,入栈时,先push进队列,然后将该队尾元素之前的所有元素出队再入队,即可满足后入先出特性。
解法二:一个队列模拟栈
点击查看代码
class MyStack {
public:
MyStack() {
this->size = 0;
}
void push(int x) {
que.push(x);
int count = 0;
while(count < this->size) {
que.push(que.front());
que.pop();
++count;
}
++this->size;
}
int pop() {
int stkTopEle = que.front();
que.pop();
--this->size;
return stkTopEle;
}
int top() {
return que.front();
}
bool empty() {
return que.empty();
}
private:
queue<int> que;
int size;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
20.有效的括号
栈的经典应用:括号匹配
点击查看代码
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for(int i = 0; i < s.size(); ++i) {
if(s[i] == '(') stk.push(')');
else if(s[i] == '{') stk.push('}');
else if(s[i] == '[') stk.push(']');
else {
if(!stk.empty() && stk.top() == s[i]) stk.pop();
else return false; //遇到右括号时若栈空或者栈顶元素不相同则必不匹配
}
}
return stk.empty(); //遍历完所有括号后若栈仍然不空说明有未匹配的左括号
}
};
遇到左括号时,不直接入栈左括号,而是入栈相匹配的右括号,这样遇到右括号时,只需看栈顶元素与此时的右括号是否相同即可
- 删除字符串中的所有相邻重复项
点击查看代码
class Solution {
public:
void reverseStr(string &s) {
for(int i = 0, j = s.size() - 1; i < j; ++i, --j)
swap(s[i], s[j]);
}
string removeDuplicates(string s) {
stack<char> stk;
for(int i = 0; i < s.size(); ++i) {
if(stk.empty() || stk.top() != s[i]) stk.push(s[i]);
else stk.pop();
}
string result;
while(!stk.empty()) {
result += stk.top();
stk.pop();
}
reverseStr(result);
return result;
}
};
遇到类似于前后匹配消除的题目均可利用栈,因为栈帮助我们记录了遍历数组当前元素时候,前一个元素是什么
2025/02/22
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性