代码随想录算法训练营day10 | 232.用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项

栈的常用接口:
stack stk;

stk.push(10);

stk.pop();

stk.top() //返回栈顶元素的引用,可作为左值,也可作为右值

stk.empty() //判空

stk.size()

队列的常用接口:
queue que;

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(); //遍历完所有括号后若栈仍然不空说明有未匹配的左括号
    }
};

遇到左括号时,不直接入栈左括号,而是入栈相匹配的右括号,这样遇到右括号时,只需看栈顶元素与此时的右括号是否相同即可

  1. 删除字符串中的所有相邻重复项
点击查看代码
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

posted @   coder小杰  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示