前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C++刷题(二):栈 + 队列

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

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

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

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

20. 有效的括号

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

代码语言:javascript
代码运行次数:0
运行
复制
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
运行
复制
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
运行
复制
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
运行
复制
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
运行
复制
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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目
  • 20. 有效的括号
  • 225. 用队列实现栈
  • 232. 用栈实现队列
  • 622. 设计循环队列
  • 面试题03.05. 栈排序
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档