面试中考察栈和队列的经典算法题

news2024/12/25 13:52:23

💝💝💝如果你对顺序表的概念与理解还存在疑惑,欢迎观看我之前的作品👉【栈和列队详解】

上篇文章👉 【面试中顺序表常考的十大题目解析】


目录

💯前言

💯栈相关题目

⭐有效的括号

⭐逆波兰表达式求值

⭐栈的压入、弹出序列

💯队列相关题目

⭐用队列实现栈

⭐用栈实现队列

💯总结


💯前言

在技术面试中,栈和队列是数据结构领域的重要考点,经常会出现各种相关的题目来考查应聘者对这两种数据结构的理解和掌握程度。以下是一些栈和队列面试中常考的题目及解析

 

💯栈相关题目

⭐有效的括号

题目链接👉【力扣】

题目描述:给定一个只包含括号 '('')''{''}''['']' 的字符串,判断字符串中的括号是否有效。有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

示例 1
输入:"()"
输出:true

示例 2
输入:"()[]{}"
输出:true

示例 3
输入:"(]"
输出:false

  

解题思路

我们可以使用来解决这个问题。遍历字符串中的每个字符,如果是左括号,就将其压入栈中。如果是右括号,就检查栈顶元素是否是对应的左括号,如果是,则弹出栈顶元素;如果不是,或者栈为空,则说明括号无效。最后,如果栈为空,则说明所有括号都匹配成功,字符串中的括号是有效的;否则,括号无效。

代码实现(C++)

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for (char c : s) {
            if (c == '(' || c == '[' || c == '{') {
                st.push(c);
            } else {
                if (st.empty()) return false;
                char top = st.top();
                if ((c == ')' && top == '(') || (c == ']' && top == '[') || (c == '}' && top == '{')) {
                    st.pop();
                } else {
                    return false;
                }
            }
        }
        return st.empty();
    }
};

⭐逆波兰表达式求值

题目链接👉【力扣】

题目描述:逆波兰表达式是一种后缀表达式,它将运算符放在操作数之后。例如,表达式 3 4 + 5 * 对应的中缀表达式是 (3 + 4) * 5。给定一个逆波兰表达式,求其求值结果。

示例
输入:["2", "1", "+", "3", "*"]
输出:9
解释:该逆波兰表达式的计算过程为:(2 + 1) * 3 = 9

解题思路

使用来解决这个问题。遍历逆波兰表达式中的每个元素,如果是数字,就将其转换为整数并压入栈中。如果是运算符,就从栈中弹出两个操作数,进行相应的运算,然后将结果压回栈中。最后,栈中剩下的唯一元素就是表达式的求值结果。

代码实现(C++)

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for (string token : tokens) {
            if (token == "+" || token == "-" || token == "*" || token == "/") {
                int num2 = st.top(); st.pop();
                int num1 = st.top(); st.pop();
                if (token == "+") st.push(num1 + num2);
                else if (token == "-") st.push(num1 - num2);
                else if (token == "*") st.push(num1 * num2);
                else st.push(num1 / num2);
            } else {
                st.push(stoi(token));
            }
        }
        return st.top();
    }
};

⭐栈的压入、弹出序列

题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 1,2,3,4,5 是某栈的压栈序列,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。

解题思路

使用一个辅助栈来模拟栈的压入和弹出操作。遍历压入序列,将元素依次压入辅助栈。同时,遍历弹出序列,如果辅助栈的栈顶元素与弹出序列的当前元素相等,就将辅助栈的栈顶元素弹出,并继续比较下一个弹出元素。如果最后辅助栈为空,则说明弹出序列是可能的;否则,弹出序列是不可能的。

代码实现(C++)

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> st;
        int i = 0, j = 0;
        while (i < pushed.size()) {
            st.push(pushed[i++]);
            while (!st.empty() && st.top() == popped[j]) {
                st.pop();
                j++;
            }
        }
        return st.empty();
    }
};

💯队列相关题目

⭐用队列实现栈

题目链接👉

题目描述:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作pushtoppop 和 empty

实现思路

  1. 入栈操作(push:将元素入队到一个非空队列中(如果两个队列都为空,任选一个即可)。
  2. 出栈操作(pop:将除了最后一个元素之外的所有元素从当前非空队列依次出队并入队到另一个空队列中,然后将最后一个元素出队,这个元素就是栈顶元素。
  3. 获取栈顶元素(top:与出栈操作类似,将除了最后一个元素之外的所有元素从当前非空队列依次出队并入队到另一个空队列中,然后记录最后一个元素的值(但不出队),最后再将这个元素入队回原来的队列。
  4. 判断栈是否为空(empty:检查两个队列是否都为空。

代码实现(C++)

class MyStack {
private:
    queue<int> q1;
    queue<int> q2;

public:
    void push(int x) {
        if (q1.empty()) {
            q2.push(x);
        } else {
            q1.push(x);
        }
    }

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

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

    bool empty() {
        return q1.empty() && q2.empty();
    }
};

⭐用栈实现队列

(一)思路分析

要用栈实现队列,同样需要利用两个栈。一个栈用于入队操作(称为输入栈),另一个栈用于出队操作(称为输出栈)。当进行入队操作时,将元素直接压入输入栈。当进行出队操作时,如果输出栈为空,将输入栈中的所有元素依次弹出并压入输出栈,然后从输出栈中弹出顶部元素,这个元素就是队头元素。

(二)代码实现

  1. 结构体定义
    typedef struct {
        Stack *inputStack;
        Stack *outputStack;
    } QueueUsingStacks;

这里定义了一个结构体,包含两个指向栈的指针,用于实现队列的功能。


2. 初始化队列

    void initQueueUsingStacks(QueueUsingStacks *queue) {
        queue->inputStack = (Stack *)malloc(sizeof(Stack));
        queue->outputStack = (Stack *)malloc(sizeof(Stack));
        initStack(queue->inputStack);
        initStack(queue->outputStack);
    }

初始化时,为两个栈分配内存空间,并分别初始化它们。


3. 入队操作

    void enqueueUsingStacks(QueueUsingStacks *queue, int element) {
        pushStack(queue->inputStack, element);
    }

入队时,将元素压入输入栈


4. 出队操作

    int dequeueUsingStacks(QueueUsingStacks *queue) {
        int element;
        if (isEmptyStack(queue->outputStack)) {
            while (!isEmptyStack(queue->inputStack)) {
                pushStack(queue->outputStack, popStack(queue->inputStack));
            }
        }
        if (!isEmptyStack(queue->outputStack)) {
            element = popStack(queue->outputStack);
            return element;
        } else {
            printf("队列为空,无法出队\n");
            return -1;
        }
    }

出队时,如果输出栈为空,将输入栈中的元素转移到输出栈中,然后从输出栈中弹出顶部元素。

 

💯总结

 

通过以上对栈和队列面试常见题目的分析与解答,希望能帮助你更好地理解和掌握这两种数据结构在面试中的应用,提高你在数据结构方面的解题能力和应对面试的信心。在实际准备面试过程中,建议你多做练习,深入理解每种数据结构的特点和操作方法,以便能够灵活运用它们解决各种问题。如果你还有其他问题或需要进一步的解释,欢迎随时提问。


💝💝💝感谢你看到最后,点个赞再走吧!💝💝💝 

以下是一个投票,欢迎你参与,让我们一起了解大家对栈和队列的认知和兴趣程度: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebSocket 2024/9/30

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器双工通信——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c;并进行双向数据传输。 与HTTP协议的区别 实现

深入解析Excel文件格式:.xls与.xlsx的差异与应用指南

在当今的数据处理和办公自动化领域&#xff0c;Microsoft Excel 无疑是一款极为重要的工具。 它不仅广泛应用于日常的数据录入、计算和图表制作&#xff0c;而且也是数据分析、财务建模等专业 领域不可或缺的软件。Excel 的文件格式经历了多个版本的迭代&#xff0c;其中 .xl…

YOLOv11改进策略【注意力机制篇】| 添加SE、CBAM、ECA、CA、Swin Transformer等注意力和多头注意力机制

前言 这篇文章带来一个经典注意力模块的汇总&#xff0c;虽然有些模块已经发布很久了&#xff0c;但后续的注意力模块也都是在此基础之上进行改进的&#xff0c;对于初学者来说还是有必要去学习了解一下&#xff0c;以加深对模块&#xff0c;模型的理解。 文章目录 前言一、为…

uniapp生物识别示例(人脸识别、指纹识别)

准备工作&#xff1a; mainfest.json设置勾选&#xff1a; 勾选完成后打 App自定义调试基座测试包 示例代码&#xff1a; <template><view class"content"><button v-if"supportSoterAuthenticationArray.includes(facial)" click"…

QT使用qss控制样式实现动态换肤

文章目录 设计QSS样式表动态加载QSS文件主函数调用QT提供了一种非常灵活的方式来使用QSS(Qt Style Sheet,类似于 CSS 的样式表),实现界面的动态换肤功能。QSS可以改变Qt应用程序中几乎所有可视组件的外观,包括颜色、字体、边框等。下面介绍一下如何通过QSS实现动态换肤。 设…

大模型时代的企业AI发展趋势浅析

在当前技术飞速进步的时代背景下&#xff0c;生成式人工智能与大型模型正逐渐成为推动产业变革的关键力量。随着人工智能技术的持续成熟与普及&#xff0c;其应用范围已从个人领域拓展至企业层面&#xff0c;广泛渗透至各个行业。那么&#xff0c;这些新兴技术究竟将为产业界带…

手把手教你使用YOLOv11训练自己数据集(含环境搭建 、数据集查找、模型训练)

一、前言 本文内含YOLOv11网络结构图 训练教程 推理教程 数据集获取等有关YOLOv11的内容&#xff01; 官方代码地址&#xff1a;https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/11 二、整体网络结构图 三、环境搭建 项目环境如下&#xf…

天融信运维安全审计系统 synRequest 远程命令执行漏洞复现

0x01 产品描述&#xff1a; 天融信运维安全审计系统TopSAG是基于自主知识产权NGTOS安全操作系统平台和多年网络安全防护经验积累研发而成&#xff0c;系统以4A管理理念为基础、安全代理为核心&#xff0c;在运维管理领域持续创新&#xff0c;为客户提供事前预防、事中监控、事后…

一文了解构建工具——Maven与Gradle的区别

目录 一、Maven和Gradle是什么&#xff1f; 构建工具介绍 Maven介绍 Gradle介绍 二、使用时的区别&#xff1a; 1、新建项目 Maven&#xff1a; Gradle&#xff1a; 2、配置项目 Maven&#xff1a; Gradle&#xff1a; 3、构建项目——生成项目的jar包 Gradle&…

Linux之实战命令20:split应用实例(五十四)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

【C++】692.前K个高频单词

692. 前K个高频单词 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 使用map统计单词的次数。map是按单词从小到大排序的。对单词再按照次数从大到小排序。有两种方法&#xff1a; 将pair<string&#xff0c;int>键值对放到vector中&#xff0c;用sort排序…

【Linux系统编程】第二十五弹---Shell编程入门:打造一个简易版Shell

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、简易的shell 1.1、输出一个命令行 1.2、获取用户命令字符串 1.3、命令行字符串分割 1.4、检查命令是否是内建命令 1.5、…

LeetCode24. 两两交换链表中的节点(2024秋季每日一题 32)

给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&#xff1a;[2,1,…

Llama微调以及Ollama部署

1 Llama微调 在基础模型的基础上&#xff0c;通过一些特定的数据集&#xff0c;将具有特定功能加在原有的模型上。 1.1 效果对比 特定数据集 未使用微调的基础模型的回答 使用微调后的回答 1.2 基础模型 基础大模型我选择Mistral-7B-v0.3-Chinese-Chat-uncensored&#x…

Label-Studio ML利用yolov8模型实现自动标注

引言 Label Studio ML 后端是一个 SDK&#xff0c;用于包装您的机器学习代码并将其转换为 Web 服务器。Web 服务器可以连接到正在运行的 Label Studio 实例&#xff0c;以自动执行标记任务。我们提供了一个示例模型库&#xff0c;您可以在自己的工作流程中使用这些模型&#x…

[Cocoa]_[初级]_[绘制文本如何设置断行方式]

场景 在开发Cocoa程序时&#xff0c;表格NSTableView是经常使用的控件。其基于View Base的视图单元格模式就是使用NSCell或其子类来控制每个单元格的呈现。当一个单元格里的文字过多时&#xff0c;需要截断超出宽度的文字&#xff0c;怎么实现&#xff1f; 说明 Cocoa下的文本…

演讲干货整理:泛能网能碳产业智能平台基于 TDengine 的升级之路

在 7 月 26 日的 TDengine 用户大会上&#xff0c;新奥数能 / 物联和数据技术召集人袁文科进行了题为《基于新一代时序数据库 TDengine 助力泛能网能碳产业智能平台底座升级》的主题演讲。他从泛能网能碳产业智能平台的业务及架构痛点出发&#xff0c;详细分享了在数据库选型、…

【多线程奇妙屋】能把进程和线程讲的这么透彻的,没有20年功夫还真不行【0基础也能看懂】

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

OpenGL ES 顶点缓冲区和布局(3)

OpenGL ES 顶点缓冲区和布局(3) 简述 顶点缓冲区的本质就是一段GPU上的显存&#xff0c;我们通过绑定顶点缓冲区的方式来将数据从CPU传到GPU。 我们之前在绘制三角形的例子中&#xff0c;我们往顶点缓冲区只传入了坐标&#xff0c;但是其实顶点是可以包含很多数据的&#xff…

指定PDF或图片多个识别区域,识别区域文字,并导出到Excel文件中

常见场景 用户有大量图片/PDF文件&#xff0c;期望能将图片/PDF中的多个区域中的文字批量识别出来&#xff0c;并导入到Excel文件中。期望工具可以批量处理、离线识别&#xff08;保证数据安全性&#xff09;。手工操作麻烦。具体场景&#xff1a;用户有工程现场照片&#xff…