Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++刷题(二):栈 + 队列

C++刷题(二):栈 + 队列

作者头像
用户11029137
发布于 2025-03-16 12:47:05
发布于 2025-03-16 12:47:05
3100
代码可运行
举报
文章被收录于专栏:编程学习编程学习
运行总次数:0
代码可运行

📝前言说明: 本专栏主要记录本人的基础算法学习以及刷题记录,使用语言为C++。 每道题我会给出LeetCode上的题号(如果有题号),题目,以及最后通过的代码。没有题号的题目大多来自牛客网。对于题目的讲解,主要是个人见解,如有不正确,欢迎指正,一起进步!

题目
  • 20. 有效的括号
  • 225. 用队列实现栈
  • 232. 用栈实现队列
  • 622. 设计循环队列
  • 面试题03.05. 栈排序

20. 有效的括号

经典的括号匹配题:利用栈。遇到左括号:入栈,遇到右括号:出栈 不过写代码时要注意:因为我们要让'(' 匹配 ')',所以遇到左括号时,直接将它对应的右括号入栈,后续可以直接字符比较判断。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for(auto ch : s)
        {
            if(ch == '('){
                st.push(')'); // 需要匹配的
            }
            else if (ch == '['){
                st.push(']');
            }
            else if (ch == '{'){
                st.push('}');
            }
            else{
                if( st.empty() || ch != st.top()){ // 这里要先判断栈是否为空
                    return false;
                }
                st.pop();
            }

        }
        return st.empty();
    }
};

225. 用队列实现栈

首先我们要了解栈的特点:先进后出,队列的特点:先进先出 因此,这道题的难点在于:如何让新入队的元素处于队头?

这道题给了我们两个队列,如果将一个队列当做主队列(即栈),另一个队列作为辅助队列,我们就可以利用辅助队列来改变新入队的元素的位置: 前提:每次操作前,辅助队列要为空。 思想:如果直接让新元素进主队列,那这个元素肯定是最后一个了,但是直接让新元素进辅助队列,那这个新元素就是辅助的第一个元素。所以我们先让新元素进入辅助队列,然后再把主队列(栈)里的元素依次出栈放入辅助队列,这样在辅助队列里新元素第一个出队列,而其他元素的出队列顺序与原来的主队列(栈)保持一致。这时候我们再交换辅助队列和主队列的身份。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyStack {
public:
    queue<int> queue1; 
    queue<int> queue2; 
    MyStack() {
        
    }
    
    void push(int x) {
        queue2.push(x); // 把新元素放到辅助队列
        while(!queue1.empty()){
            queue2.push(queue1.front()); // 依次将栈的元素放入辅助队列
            queue1.pop();
        }
        swap(queue1, queue2);
    }
    
    int pop() {
        int r = queue1.front();
        queue1.pop();
        return r;
    }
    
    int top() {
        return queue1.front();
    }
    
    bool empty() {
        return queue1.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();
 */

232. 用栈实现队列

只需要让一个栈进,一个栈负责出就行了。当一个栈的元素全部倒入另一个栈,这时候元素的出入顺序就会完全改变一次。(为了节约时间,我们只在outStack里面元素彻底为空且遇到出栈需求时,才将inStack的数据倒入`outStack)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyQueue {
public:

    stack<int> inStack, outStack;

    void in_to_out(){ // 倒转
        while(!inStack.empty()){
            outStack.push(inStack.top());
            inStack.pop();
        }
    }

    MyQueue() {
        
    }
    
    void push(int x) {
        inStack.push(x);
    }
    
    int pop() {
        if(outStack.empty()){
            in_to_out();
        }
        int r = outStack.top();
        outStack.pop(); 
        return r;
    }
    
    int peek() {
        if(outStack.empty()){
            in_to_out();
        }
        return outStack.top();
    }
    
    bool empty() {
        return inStack.empty() && outStack.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();
 */

622. 设计循环队列

下面解法以数组为例: 环形队列的关键在于:1,如何通过取模来达到走环的效果;2,如何判断队列满和空的情况。 对于循环:当一个数+1时可能超出最大值,则需要%来控制此数的大小任然在下标范围内; 对于判空:起始时front指针和rear指针都指向空;对于满,我们可以牺牲一个空间,即:当rear+1 == front的时候为满(但注意rear + 1要确保在数组下标内)。 下面做法以front的后一位为第一个数据位为例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyCircularQueue {
public:

    // 用数组来模拟循环队列,让front指向的位置为空,front下一个位置才有节点
    // front == rear时为空,当 rear + 1 == front 时为满 
    MyCircularQueue(int k) 
    {
        capacity = k;
        front = rear = 0;
        que = vector<int> (k+1); // 比容量多开一个空间,则数组下标为[0, k](后续我们要让rear和front的下标在这个范围内,不然会越界)
    }
    
    bool enQueue(int value) {
        if(isFull()){
            return false;
        }
        rear = (rear + 1) % (capacity + 1);  
        que[rear] = value;
        return true;
    }
    
    bool deQueue() {
        if(isEmpty()){
            return false;
        }
        front = (front + 1) % (capacity + 1);
        return true;
    }
    
    int Front() {
        if(isEmpty()){
            return -1;
        }
        return que[(front + 1) % (capacity + 1)];
    }
    
    int Rear() {
        if(isEmpty()){
            return -1;
        }
        return que[rear];
    }
    
    bool isEmpty() {
        return rear == front;
    }
    
    bool isFull() {
        return ((rear + 1) % (capacity + 1)) == front;
    }

private:
    int front;
    int rear;
    int capacity;
    vector<int> que;
};

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * MyCircularQueue* obj = new MyCircularQueue(k);
 * bool param_1 = obj->enQueue(value);
 * bool param_2 = obj->deQueue();
 * int param_3 = obj->Front();
 * int param_4 = obj->Rear();
 * bool param_5 = obj->isEmpty();
 * bool param_6 = obj->isFull();
 */

面试题03.05. 栈排序

这道题的题目表述不清楚,看示例可以发现,实际上是往栈里面插入元素,要保证插入后的顺序从栈底到栈顶是从大到小的。 我们只需要将每次要插入的元素和栈中已经有的元素作比较,找到合适的位置插入。 如:栈顶元素为t,要插入元素为val,如果val < t,就直接入栈,否则,先让t进入辅助栈,重复此过程,直到找到合适的位置插入,插入完后,把st2的元素倒回来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class SortedStack {
public:
    SortedStack() {
        
    }
    
    void push(int val) {
        while( !st1.empty() && st1.top() < val){
            st2.push(st1.top()); // 把st1的元素暂存到st2
            st1.pop();
        }
        st1.push(val);
        // 把st2的元素倒回来
        while(!st2.empty()){
            st1.push(st2.top());
            st2.pop();
        }
        

    }
    
    void pop() {
        if(!st1.empty()){
            st1.pop();
        }
    }
    
    int peek() {
        if(!st1.empty()){
            return st1.top();
        }
        return -1;
    }
    
    bool isEmpty() {
        return st1.empty();
    }
private:
    stack<int> st1, st2;
};

/**
 * Your SortedStack object will be instantiated and called as such:
 * SortedStack* obj = new SortedStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->isEmpty();
 */
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
leecode刷题(26)-- 用栈实现队列
所以我们只用一个栈的话是无法实现队列的操作的。不妨换个思路,我们用两个栈来实现队列:
希希里之海
2019/05/14
3420
leecode刷题(26)-- 用栈实现队列
LeetCode | 225.用队列实现栈
上面的题就是 用队列实现栈 题目的截图,同时 LeetCode 给出了一个类的定义,然后要求实现 用队列实现栈 的完整的数据结构。这次我没有使用 C 语言,而是使用了 C++ 语言,整个类的定义如下:
码农UP2U
2020/08/26
2850
LeetCode | 225.用队列实现栈
【C++】五道经典面试题带你玩转栈与队列
https://leetcode.cn/problems/min-stack/
修修修也
2024/08/06
1180
【C++】五道经典面试题带你玩转栈与队列
栈和队列专项练习
为满时: 此时需要考虑空间的问题, 1.若只取k个空间 需要进入数据时,tail被赋值,tail向后移一个,当最后一块空间被赋值时,tail回到下标为0的数组中, 此时tail ==front与判断空的条件相同 ,所以不成立。
lovevivi
2022/11/10
2880
栈和队列专项练习
【C++】STL--stack
后进先出(LIFO):Stack容器遵循后进先出的原则,即最后进入栈的元素最先被移出栈。
用户11375356
2024/11/22
710
【C++】STL--stack
有关栈和队列应用的oj题讲解
我们首先调用创建好的队列代码,然后假设令这两个队列作为一个栈,由于我们画图可以得出一个结论:
羑悻的小杀马特.
2025/01/23
380
有关栈和队列应用的oj题讲解
OJ习题 篇2
可以用快慢指针,快指针表示遍历数组到达的下标位置,慢指针表示下一个不同元素要填入的下标位置,初始时两个指针都指向下标1,这是为了体现慢指针记录不重复的数据个数。 删除重复项和找不重复的项效果是一样的。
_小羊_
2024/10/16
780
OJ习题 篇2
驾驭栈和队列,首先逃不开这些(有效括号、栈和队列相互模拟、循环队列)
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
一枕眠秋雨
2024/03/11
960
驾驭栈和队列,首先逃不开这些(有效括号、栈和队列相互模拟、循环队列)
【数据算法与结构】栈与队列篇
思路: pushV中的元素依次入栈,和popV中的元素比较,如果相同就出栈,遍历结束后,如果栈为空,那么就说明是正确的弹出顺序.
xxxflower
2024/03/11
890
【数据算法与结构】栈与队列篇
LeetCode 232. 用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):
SakuraTears
2022/01/13
1660
Java的栈与队列以及代码实现
栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶 栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等。 例如这把枪,第一发子弹是最后发射的,第一发子弹在栈底,而最新安装上去的子弹在栈的顶部,只有将上面的子弹打完(栈顶的数据走完),最后一发子弹才会射出
如烟花般绚烂却又稍纵即逝
2024/11/26
1460
Java的栈与队列以及代码实现
C语言每日一题(40)栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
对编程一片赤诚的小吴
2024/01/23
1520
C语言中的循环队列与栈、队列之间的转换实现
在数据结构的学习中,栈(Stack)和队列(Queue)是两个非常重要的概念。它们分别遵循着后进先出(LIFO)和先进先出(FIFO)的原则。在某些情况下,我们可能需要通过栈来模拟队列,或者通过队列来模拟栈的行为。本文将详细介绍这两种数据结构,并提供相应的C语言实现代码和图解。
小志biubiu
2025/02/27
520
C语言中的循环队列与栈、队列之间的转换实现
leetcode:用栈实现队列(先进先出)
用栈实现队列最主要的是实现队列先进先出的特点,而栈的特点是后进先出,那么我们可以用两个栈来实现:
用户10925563
2024/06/04
780
leetcode:用栈实现队列(先进先出)
LeetCode刷题(8)【栈&队列】用栈实现队列(C语言)
232. 用栈实现队列 - 力扣(LeetCode) (leetcode-cn.com)
半生瓜的blog
2023/05/12
5580
LeetCode刷题(8)【栈&队列】用栈实现队列(C语言)
你能用栈实现队列,再用队列实现栈吗?
上一篇文章我们一起学习了栈和队列这两个数据结构,今天我们来小试牛刀用两道LeetCode中的经典问题来练练手。
TechFlow-承志
2023/03/02
1.1K0
你能用栈实现队列,再用队列实现栈吗?
数据结构之队列详解(包含例题)
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
用户11316056
2024/10/16
1570
数据结构之队列详解(包含例题)
数据结构初步(九)- 栈和队列oj练习
,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左括号。 示例 1: 输入:
怠惰的未禾
2023/04/27
3250
数据结构初步(九)- 栈和队列oj练习
数据结构之队列的实现(附源码)
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
用户10923276
2024/03/28
1370
数据结构之队列的实现(附源码)
栈和队列深入浅出
1. 概念: 栈一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守先进后出的原则。
用户11305962
2024/10/09
1130
栈和队列深入浅出
相关推荐
leecode刷题(26)-- 用栈实现队列
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验