• 算法刷题-栈与队列


    算法刷题-栈与队列

    232. 用栈实现队列

    请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

    实现 MyQueue 类:

    • void push(int x) 将元素 x 推到队列的末尾
    • int pop() 从队列的开头移除并返回元素
    • int peek() 返回队列开头的元素
    • boolean empty() 如果队列为空,返回 true ;否则,返回 false

    思路

    开两个栈inout,in负责加入元素,out负责弹出元素

    • 入队:将元素塞入in中
    • 出队,如果out为空,那么就把in中元素一个一个弹出塞到out中,这时候元素就会和刚加入的时候相反,满足队列的要求。然后再从out中弹出元素
    • peek:就是先让out顶部元素出队,然后入队,这样就不会删除元素,但是可以获取到栈顶的值
    • empty:判断in和out都为空,那么说明队列就是空的

    代码

    class MyQueue {
    public:
        stack<int> in;
        stack<int> out;
        MyQueue() {
    
        }
        
        void push(int x) {
            in.push(x);
        }
        
        int pop() {
            if(out.empty()){
                while(!in.empty()){
                    auto t=in.top();
                    in.pop();
                    out.push(t);
                }
            }
            int res=out.top();
            out.pop();
            return res;
        }
        
        int peek() {
            int res=  this->pop();
            out.push(res);
            return res;
        }
        
        bool empty() {
            return in.empty()&&out.empty();
        }
    };
    
    /**
     * 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();
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    225. 用队列实现栈

    请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

    实现 MyStack 类:

    • void push(int x) 将元素 x 压入栈顶。
    • int pop() 移除并返回栈顶元素。
    • int top() 返回栈顶元素。
    • boolean empty() 如果栈是空的,返回 true ;否则,返回 false

    思路

    q1作为存储元素的队列,q2作为备份
    删除元素的时候先把前n-1个元素放到q2里面,再删去一个元素
    然后再把q2赋值给q1,再把q2清空

    代码

    class MyStack {
    public:
        queue<int> q1,q2;
        MyStack() {
    
        }
        
        void push(int x) {
            q1.push(x);
        }
        
        int pop() {
            auto t=q1.back();
            int sz=q1.size();
            sz--;
            while(sz--){
                q2.push(q1.front());
                q1.pop();
            }
            q1.pop();
            q1=q2;
            while(q2.size()) q2.pop();
            return t;
        }
        
        int top() {
            return q1.back();
        }
        
        bool empty() {
            return q1.empty();
        }
    };
    
    /**
     * 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();
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    20. 有效的括号

    给定一个只包括 '('')''{''}''['']'字符串 s ,判断字符串是否有效。

    有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。
    3. 每个右括号都有一个对应的相同类型的左括号。

    思路

    使用一个栈记录左括号,
    扫描整个字符串,

    • 如果是左括号就加入到栈中
    • 如果是右括号,那就看栈顶元素能否匹配,不能就是不符合题意

    代码

    class Solution {
    public:
        bool isValid(string s) {
            stack<char> stk;
            for(char c:s){
                if(c=='('||c=='{'||c=='[') stk.push(c);
                else{
                    bool ok=0;
                    if(stk.empty()) return false;
                    if(c==')'&&stk.top()=='(') stk.pop(),ok=1;
                    if(c=='}'&&stk.top()=='{') stk.pop(),ok=1;
                    if(c==']'&&stk.top()=='[') stk.pop(),ok=1;
                    if(!ok) return false;
                }
            }
            cout<<stk.size()<<endl;
            if(stk.empty()) return true;
            return false;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ``

    1047. 删除字符串中的所有相邻重复项

    给出由小写字母组成的字符串 S重复项删除操作会选择两个相邻且相同的字母,并删除它们。

    在 S 上反复执行重复项删除操作,直到无法继续删除。

    在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

    思路

    用栈记录元素,遍历整个字符串, 如果当前元素和栈顶元素相同,那么就将栈顶元素删除,否则就把当前元素加入到栈中。

    代码

    class Solution {
    public:
        string removeDuplicates(string s) {
            stack<char> t;
            for(char c:s){
                if(t.size()){
                    if(t.top()==c) t.pop();
                    else t.push(c);
                }else{
                    t.push(c);
                }
            }
            string res;
            while(!t.empty()) res+=t.top(),t.pop();
            reverse(res.begin(),res.end());
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    Navicat for MySQL 视图创建使用方法
    【代码笔记】高并发场景下问题解决思路
    LeetCode //C - 130. Surrounded Regions
    从土木转行做软件测试,工资翻了好几倍,我想和大家聊聊我提桶跑路的经历
    AM@隐函数@隐函数求导@幂指函数求导@参数式函数求导
    盘点有趣的人工智能开源项目一
    WANem弱网环境模拟工具的使用探索
    macOS 查验国家税务总局发票
    开源大数据比对平台设计与实践—dataCompare
    物联网模块开发:全面助力万物物联,开启物联网时代
  • 原文地址:https://blog.csdn.net/m0_74085417/article/details/134082915