C++《stack和queue的一些OJ题目》

本文详细介绍了四个C++编程题目,涉及stack和queue的数据结构应用,包括最小栈的实现、栈的压入和弹出序列的判断、逆波兰表达式的求解以及如何用队列模拟栈的功能。每个题目都给出了思路分析和代码实现。
摘要由CSDN通过智能技术生成

本文主要讲解C++中stack和queue的一些OJ题目



1、最小栈

在这里插入图片描述
思路1

使用两个栈,st用来进行常规的入栈操作。minst栈也同步进行,但是有要求,该栈主要负责返回最小值。当minst为空或者val比minst栈顶元素小才入栈。当minst的栈顶元素和st的栈顶栈
在这里插入图片描述
在这里插入图片描述

代码如下:

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) 
    {
        if(minst.empty() || minst.top() >= val)
        {
            minst.push(val);
        }
        st.push(val);
    }
    
    void pop() 
    {
        if(st.top() == minst.top())
        {
            minst.pop();
        }
        st.pop();
    }
    
    int top() 
    {
        return st.top();
    }
    
    int getMin() 
    {
        return minst.top();
    }
private:
     stack<int> st;
     stack<int> minst;

};

但是,当全部元素相同时,我们的空间复杂度是O(N)了。这时,我们可以将最小栈设计成结构体,结构体里面存储的是元素的值和个数。

思路2

为了解决元素相同时,消耗内存。和方法思路一样,只是此时入栈的是一个结构体数据。{1,12},1表示数据,12表示出现的次数

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) 
    {
        if(_minst.empty())
        {
            Data d;
            d._val = val;
            d._count++;
            _minst.push(d);
        }
        else if(_minst.top()._val == val)
        {
            _minst.top()._count++;
        }
        else if(_minst.top()._val >= val)
        {
            Data d;
            d._val = val;
            d._count++;
            _minst.push(d);
        }
        
        _st.push(val);
    }
    
    void pop() 
    {
        if((_minst.top()._val == _st.top()) && _minst.top()._count > 1)
        {
            _minst.top()._count--;
        }
        else if((_minst.top()._val == _st.top()) && _minst.top()._count == 1)
        {
            _minst.pop();
        }
        _st.pop();
    }
    
    int top() 
    {
        return _st.top();
    }
    
    int getMin() 
    {
        return _minst.top()._val;
    }
private:
    stack<int> _st;

    //定义一个结构体,当入栈时候,入的是一个结构体[{1,12}],表示1有12个
    struct Data
    {
        int _val = 0;
        int _count = 0;
    };
    stack<Data> _minst;
};

2、栈的压入、弹出序列

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

代码如下:

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV)
    {
        stack<int> st;
        int pushi = 0,popi = 0;
 
        //遍历pushV进行入栈操作
        while(pushi < pushV.size())
        {
            //入栈
            st.push(pushV[pushi++]);
 
            //和比较popV[]比较进行出栈操作
            while(!st.empty() && st.top() == popV[popi])
            {
                st.pop();
                popi++;
            }
        }
        return st.empty();
    }
};

3、逆波兰表达式

在这里插入图片描述

注意:逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * )

逆波兰表达式主要有以下两个优点:

1.去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
2.适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中

在这里插入图片描述

class Solution {
public:
    int evalRPN(vector<string>& tokens) 
    {
        stack<int> st;
        for(auto& str : tokens)
        {
            if(!(str == "+" || str == "-" || str == "*" || str == "/"))
            {
                st.push(stoi(str)); //操作数转化为整形入栈
            }
            else
            {
                //操作符取栈顶的两的元素出栈进行运算,先是右操作数,再是左操作数
                int right = st.top();
                st.pop();

                int left = st.top();
                st.pop();

                int ret;
                switch(str[0])
                {
                    case '+':
                        st.push(left + right);
                        break;
                     case '-':
                        st.push(left - right);
                        break;
                    case '*':
                        st.push(left * right);
                        break;
                    case '/':
                        st.push(left / right);
                        break;   
                }
            }
        }
        return st.top();
    }
};

4、用队列实现栈

在这里插入图片描述
思路:定义两个栈,q1和q2。其中q1用于存储栈的元素,q2用于辅助操作。

具体实现方法是:在每次压入元素时,将元素先插入到q2的队尾,然后将q1中的所有元素依次弹出并插入到q2中,最后将q1和q2交换。这样,每次操作后,q1中的队头元素就是最后一个压入的元素,也就是栈顶元素。在弹出元素时,直接从q1中弹出队头元素即可。在获取栈顶元素时,直接返回q1中的队头元素即可。在判断栈是否为空时,只需要检查q1是否为空即可。
在这里插入图片描述

class MyStack {
public:
    queue<int> q1 ,q2;
    MyStack() {}
    
    void push(int x) {
        q2.push(x);
        while(!q1.empty())
        {
            q2.push(q1.front());
            q1.pop();
        }
        swap(q1,q2);
    }
    
    int pop() {
        int front=q1.front();
        q1.pop();
        return front;
    }
    
    int top() {
        int front=q1.front();
        return front;
    }
    
    bool empty() 
    { return q1.empty();}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值