【LeetCode刷题】栈和队列题目练习~

在这里插入图片描述

1. 题目:155.最小栈

在这里插入图片描述

思路分析:

从解释那段代码调用,我们可以知道MinStack是一个很普通的栈,就多一个函数而已。所以就可以在MinStack的属性里加一个stack<int>,再加一个可以时刻记录栈内最小值的容器就可以。

思路1:两个栈实现最小栈

设计两个栈,一个正常栈(s1),一个用于记录正常栈每次push或者pop后的最小值(minS)。要获得MinStack的最小值,只需要访问minS的top就可以。

代码实现:

class MinStack {
public:
    MinStack() {}
    
    void push(int val) {
        s1.push(val);
        if(minS.empty()||val<minS.top()) minS.push(val);
        else minS.push(minS.top());
    }
    
    void pop() {
        s1.pop();
        minS.pop();
    }
    
    int top() {
        return s1.top();
    }
    
    int getMin() {
        return minS.top();
    }
private:
    stack<int> s1;
    stack<int> minS;
};

【LeetCode链接:155.最小栈】

2.题目: JZ31 栈的压入、弹出序列

在这里插入图片描述

思路分析:

平时我们做这样的选择题是怎么做的?自己是不是要模拟实现一下。所以这里我们也同样可以来模拟实现一下,看匹不匹配。

思路1:模拟实现

  • 模拟实现,判断栈的出入顺序匹不匹配,肯定要有个栈s1。
  • 再来过程,pushV把数据push到栈里,每次push后,栈顶元素与序列popV头元素(或者指针元素)对比,若相等,两个都头删(栈头删,popV指针后移),再比较,直到不相等,然后再接着pushV进栈(vector没有头删,所以用指针记录好些)。
  • 结果判断:可以判断popV的指针位置,也可以判断栈s1是否已经pop完了。
    代码实现:
class Solution {
public:
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        // write code here
        stack<int> s;
        int j=0;
        for(int i=0;i<pushV.size();i++)
        {
            s.push(pushV[i]);
            while(!s.empty())
            {
                 if(s.top()==popV[j])
                {
                s.pop();
                j++;
                }
                else break;
            }
        }
        return j==popV.size();
    }
};

【牛客链接:JZ31 栈的压入、弹出序列】

3.题目: 150.逆波兰表达式求值

在这里插入图片描述

思路分析:

这题的要求就是计算逆波兰表达式的值,也叫后缀表达式(运算符放到后面),计算规则很简单,主要是设计一些判断。

运算规则:符号前两个数字,通过这个运算符计算后再次存入,直到把最后一个运算符运算结束。

思路1:暴力

遍历tokens,是数字就按顺序存在容器里,遇到运算符,就取出最近插入的两个数字计算,注意前面的减后面的(减法和除法注意),然后再把计算结果返回到容器里。直到遍历完。
代码实现:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> s;
        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/") 
            {
                if(tokens[i]=="+") 
                {
                    int k=s.top();
                    s.pop();
                    k+=s.top();
                    s.pop();
                    s.push(k);
                }
                else if(tokens[i]=="-") 
                {
                    int k=s.top();
                    s.pop();
                    k=s.top()-k;
                    s.pop();
                    s.push(k);
                }
                else if(tokens[i]=="*") 
                {
                   int k=s.top();
                    s.pop();
                    k*=s.top();
                    s.pop();
                    s.push(k);
                }
                else if(tokens[i]=="/") 
                {
                   int k=s.top();
                    s.pop();
                    k =s.top()/k;
                    s.pop();
                    s.push(k);
                }
            }
            else s.push(stoi(tokens[i]));
        }
        return s.top();
    }
};

【LeetCode链接:150.逆波兰表达式求值】

4.题目:232.用栈实现队列

在这里插入图片描述

思路分析:

用栈来实现队列,要从先进后出变到先进先出。

思路1:两个栈

其实只是需要一个辅助栈就可以了。正常栈push进数据,再要pop或者返回top的时候,几把数据push到辅助栈里,然后辅助栈pop、top都可以。

代码实现:

class MyQueue {
public:
    void push(int x) { s1.push(x); }

    int pop() {
        if (s2.empty())
            while (!s1.empty()) {
                s2.push(s1.top());
                s1.pop();
            }
        int k = s2.top();
        s2.pop();
        return k;
    }

    int peek() {
        if (s2.empty())
            while (!s1.empty()) {
                s2.push(s1.top());
                s1.pop();
            }
        return s2.top();
    }

    bool empty() { return s1.empty() && s2.empty(); }
    stack<int> s1;			//正常栈
    stack<int> s2;			//辅助栈
};

【LeetCode链接:232.用栈实现队列】

5.题目:225.用队列实现栈

在这里插入图片描述

思路分析:

这种题主要是设计,思路方面比较明确的。用队列实现栈。

思路1:一个队列实现

一个队列思路就是:一个元素进去,要保证它是在front位置,怎么保证,把前面的所有元素再一次push进队列就可以。

代码实现:

class MyStack {
public:
    queue<int> q;

    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
        int n = q.size();
        q.push(x);
        for (int i = 0; i < n; i++) {
            q.push(q.front());
            q.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int r = q.front();
        q.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {
        int r = q.front();
        return r;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return q.empty();
    }
};

作者:力扣官方题解
来源:力扣(LeetCode)

思路2:两个队列:入栈O(n),出栈O(1)

入栈O(n),出栈O(1): 这就说明在push时候导元素。一个栈保持空队列,每次push就往里push,再把另一个栈顺序的队列的元素全部导到这个刚push一个的元素里。然后交换两个队列,push队列依旧是空,顺序队列依旧顺序和栈要求顺序一样(pop、front就是后进的元素)
代码实现:

class MyStack {
public:
    queue<int> queue1;
    queue<int> queue2;

    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
        queue2.push(x);
        while (!queue1.empty()) {
            queue2.push(queue1.front());
            queue1.pop();
        }
        swap(queue1, queue2);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int r = queue1.front();
        queue1.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {
        int r = queue1.front();
        return r;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return queue1.empty();
    }
};

作者:力扣官方题解
来源:力扣(LeetCode)

思路3:两个队列:入栈O(1),出栈O(n)

入栈O(1),出栈O(n): 这就说明pop处导元素。一个队列只是push进,不做其他处理。只有到了pop时候,就把这个队列的元素除了最后进的元素外,其他全部push到第二个队列。再次pop的话,就用第二个队列做同样的操作。top的话只需要看哪个队列不为空,返回最后一个元素就可以。
代码实现:

class MyStack {
public:
    void push(int x) { q1.push(x); }

    int pop() {
        int k;
        if (!q1.empty()) {
            while (q1.size() > 1) {
                q2.push(q1.front());
                q1.pop();
            }
            k = q1.front();
            q1.pop();
        } else {
            while (q2.size() > 1) {
                q1.push(q2.front());
                q2.pop();
            }
            k = q2.front();
            q2.pop();
        }

        return k;
    }

    int top() {
        if (!q1.empty())
            return q1.back();
        else
            return q2.back();
    }

    bool empty() { return q1.empty() && q2.empty(); }
    queue<int> q1;
    queue<int> q2;
};

【LeetCode链接:225.用队列实现栈】

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖胖龙大兄很忙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值