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

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

1. 题目:155.最小栈

思路分析:

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

思路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.用队列实现栈】

相关文章
|
4天前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
2月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
82 2
|
4天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
18 1
|
2月前
|
Python
【Leetcode刷题Python】1467. 两个盒子中球的颜色数相同的概率
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
24 0
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
44 6
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
37 4
|
2月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
38 7
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
20 4
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
42 5