栈和队列相关知识题目

栈的底层原理

栈(Stack)是一种后进先出(LIFO)​的线性数据结构,所有操作(如插入、删除)仅在栈顶进行。它的底层实现可以是数组或链表,具体取决于编程语言和应用场景。

1.基于数组实现:使用连续内存的数组存储元素,通过一个指针(如 top)标记栈顶位置。

核心操作:入栈(Push)​:将元素放入 top 位置,top 指针后移。​

出栈(Pop)​:返回 top-1 位置的元素,top 指针前移。

2. 基于链表(链式存储):使用单向链表(头插法)存储元素,链表的头节点作为栈顶。

入栈(Push)​:将新节点插入链表头部。

出栈(Pop)​:删除链表头节点并返回其值。

栈的应用场景

函数调用与递归:操作系统自动管理函数调用栈。
​括号匹配:检查表达式中的括号是否成对。
​表达式求值:中缀表达式转后缀表达式(逆波兰式)。
​撤销操作(Undo)​:编辑器中的操作历史栈。
​深度优先搜索(DFS)​:用栈保存遍历路径

对应题目 

用栈实现队列用栈实现队列用栈实现队列

思想:用两个栈来模拟队列,由于队列是先进先出,所以设置两个栈,一个入队栈,一个出队栈

import java.util.Deque;
import java.util.ArrayDeque;class MyQueue {private Deque<Integer> inputStack;private Deque<Integer> outputStack;public MyQueue() {inputStack = new ArrayDeque<>();outputStack = new ArrayDeque<>();}// 入队:直接压入输入栈public void push(int x) {inputStack.push(x);}// 出队:若输出栈为空,先转移元素public int pop() {if (outputStack.isEmpty()) {transferInputToOutput();}return outputStack.pop();}// 查看队首元素:类似出队但不删除public int peek() {if (outputStack.isEmpty()) {transferInputToOutput();}return outputStack.peek();}// 判断队列是否为空public boolean empty() {return inputStack.isEmpty() && outputStack.isEmpty();}// 将输入栈元素转移到输出栈(反转顺序)private void transferInputToOutput() {while (!inputStack.isEmpty()) {outputStack.push(inputStack.pop());}}
}

用队列实现栈用队列实现栈用队列实现栈用队列实现栈

思想:队列模拟栈,使用两个队列来模拟,一个主队列,一个副队列

核心思想
  • 维护两个队列:一个主队列(mainQueue)和一个辅助队列(tempQueue)。
  • 入栈(Push)​:直接将元素加入主队列。
  • 出栈(Pop)​:将主队列中除最后一个元素外的所有元素转移到辅助队列,弹出最后一个元素,最后交换主队列和辅助队列的角色。
操作步骤
  1. Push(入栈)​
    • 将新元素直接加入主队列。
  2. Pop(出栈)​
    • 将主队列中的前 n-1 个元素依次出队并加入辅助队列。
    • 弹出主队列的最后一个元素(即栈顶元素)。
    • 交换主队列和辅助队列的角色,以便下次操作。
    • import java.util.LinkedList;
      import java.util.Queue;class MyStack {private Queue<Integer> mainQueue;private Queue<Integer> tempQueue;public MyStack() {mainQueue = new LinkedList<>();tempQueue = new LinkedList<>();}// 入栈:直接加入主队列public void push(int x) {mainQueue.offer(x);}// 出栈:转移前n-1个元素后弹出最后一个元素public int pop() {while (mainQueue.size() > 1) {tempQueue.offer(mainQueue.poll());}int top = mainQueue.poll();// 交换主队列和辅助队列Queue<Integer> swap = mainQueue;mainQueue = tempQueue;tempQueue = swap;return top;}// 查看栈顶元素:逻辑同pop,但需将元素重新放回主队列public int top() {while (mainQueue.size() > 1) {tempQueue.offer(mainQueue.poll());}int top = mainQueue.poll();tempQueue.offer(top); // 重新加入队列// 交换队列Queue<Integer> swap = mainQueue;mainQueue = tempQueue;tempQueue = swap;return top;}// 判空:主队列是否为空public boolean empty() {return mainQueue.isEmpty();}
      }

有效的括号有效的括号

思想:括号匹配是使用栈解决的经典问题。遇见左括号就压入栈中,遇见右括号,先判断栈是否为空,在导出栈顶元素判断,若最后栈为空则说明符号匹配成功,若左右括号不匹配也返回失败。

class Solution {public boolean isValid(String s) {Stack<Character> stack =new Stack<>();for (int i=0;i<s.length();i++){char c1 = s.charAt(i);if(c1 =='{' ||c1 =='(' ||c1 =='['){stack.push(c1);}else if(c1 =='}' ||c1 ==')' ||c1 ==']'){if(stack.isEmpty()){return false;}else if (stack.peek() =='{' && c1 =='}'){stack.pop();}else if (stack.peek() =='(' && c1 ==')'){stack.pop();}else if (stack.peek() =='[' && c1 ==']'){stack.pop();}else{return false;}}}return stack.isEmpty();}
}

删除字符串中的所有相邻重复项 

思想:比较简单,需要注意一个点就是,栈无法直接转化成数组,即stack.toString()是错误的
要创建数组,将栈中的元素都出栈即可

class Solution {public String removeDuplicates(String s) {Stack<Character> stack =new Stack<>();for(int i=0;i<s.length();i++){char c = s.charAt(i);if(stack.isEmpty() || c != stack.peek()){stack.push(c);}else {stack.pop();}}String str = "";//剩余的元素即为不重复的元素while (!stack.isEmpty()) {str = s.pop() + str;}return str;}
}

逆波兰表达式求值

要注意下述代码中的几个问题:
1.因为字符串表示的是整数的加减乘除运算,所以定义栈的时候要采取整型Stack<Integer> stack =new Stack<>();
2.定义两个变量分别存储前两个操作数,但要注意操作数的顺序,因为先进后出,所以第一个出来的是第二个操作数
3.巧用switch分支结构,先做判断,在压入栈
4.最后不是输出整个栈的元素,方法要求的返回表达式值的整数,所以要做类型转换Integer.valueOf(token)

5.由于leetcode 内置jdk的问题,不能使用==判断字符串是否相等,只能用equals。并且字符相等用双引号

class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack =new Stack<>();int a,b,c;for(String token :tokens){if(token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/") ){b = stack.pop();//第二个操作数a = stack.pop();//第一个操作数c = switch(token){case "+" -> a+b;case "-" -> a-b;case "*" -> a*b;case "/" -> a/b;default ->  0;};stack.push(c);}else {stack.push(Integer.valueOf(token));}}return stack.pop();}
}

有效的括号用队列实现栈用队列实现栈用队列实现栈

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

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

相关文章

【实战案例】永洪vividime:精准赋能零售行业,实现数据洞察与业务增长

在零售食品行业变革加速、市场竞争白热化的背景下&#xff0c;XX集团作为休闲食品领域头部企业&#xff0c;面临消费趋势变化、宏观经济承压及业绩增长乏力的多重挑战。为破解增长困境&#xff0c;集团将“收入增长金额”确立为核心战略指标&#xff08;北极星指标&#xff09;…

一些题目记录

别人面经题目记录 https://zhuanlan.zhihu.com/p/32626732052 实现 NMS&#xff0c;七八次&#xff0c;很高频&#xff1b; 实现 MultiHeadSelfAttention&#xff0c;大概 三四次&#xff1b; 用 Numpy 或者 List 实现MLP 的前向和反向&#xff0c;4次&#xff1b; Leetcode …

面试题分享-多线程顺序打印奇偶数

目录 1.题目详情 2.解题思路 2.1.分析题目 2.2.解析思路 3.代码实现 4.运行结果 1.题目详情 昨天刷抖音&#xff0c;遇到一个面试题&#xff0c;描述如下&#xff1a; 请使用两个线程&#xff0c;分别顺序交替打印奇数和偶数&#xff0c;直到10为止。例如有两个线程&#…

模型 杜根定律

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。信心>能力、行动导向、未来时态。 1 杜根定律的应用 1.1 公共政策博弈——底特律市长杜根的保险改革攻坚战 核心挑战&#xff1a;底特律市长Mike Duggan面临汽车保险费率畸高导致居民陷入贫困循环的…

关于在vscode中的Linux 0.11 应用程序项目的生成和运行

首先我们需要需要查看镜像文件 查看软盘镜像文件 floppyb.img 中的内容 在 VSCode 的“Terminal”菜单中选择“Run Build Task...”&#xff0c;会在 VSCode 的顶部中间位置弹出一个 可以执行的 Task 列表&#xff0c;选择其中的“打开 floppyb.img”后会使用 Floppy Editor …

使用CSS3实现炫酷的3D视差滚动效果

使用CSS3实现炫酷的3D视差滚动效果 这里写目录标题 使用CSS3实现炫酷的3D视差滚动效果项目概述核心技术实现1. 3D空间的创建2. 视差层级设置3. 动画效果实现流星动画月亮发光效果 技术难点与解决方案1. 层级重叠问题2. 性能优化3. 响应式适配 开发心得总结 项目概述 在这个项目…

作业12 (2023-05-15 指针概念)

第1题/共11题【单选题】 关于指针的概念,错误的是:( ) A.指针变量是用来存放地址的变量 B.指针变量中存的有效地址可以唯一指向内存中的一块区域 C.野指针也可以正常使用 D.局部指针变量不初始化就是野指针 回答正确 答案解析: A:正确,指针变量中存储的是一个地址,指…

【ESP32S3】esp32获取串口数据并通过http上传到前端

通过前面的学习&#xff08;前面没发过&#xff0c;因为其实就是跑它的demo&#xff09;了解到串口配置以及开启线程实现功能的工作流程&#xff0c;与此同时还有esp32作为STA节点&#xff0c;将数据通过http发送到服务器。 将这两者联合 其实是可以得到一个&#xff1a;esp32获…

《鸿蒙携手AI:解锁智慧出行底层逻辑》

在科技飞速发展的当下&#xff0c;智慧出行成为人们对未来交通的美好期许&#xff0c;而鸿蒙系统与人工智能的深度融合&#xff0c;正为这一愿景的实现提供强大助力。从技术原理角度深入剖析&#xff0c;鸿蒙系统究竟如何支撑人工智能在智慧出行场景中的应用呢&#xff1f;这背…

MyBatis-Plus缓存机制深度解析与SpringBoot整合实战

一、MyBatis-Plus缓存机制全景解析 MyBatis-Plus在MyBatis原生缓存基础上进行了深度增强,形成了多层次的缓存体系: 1. 缓存层级架构 应用层 ├── MP扩展缓存(多租户/逻辑删除) ├── 二级缓存(Mapper级别,跨Session共享) └── 一级缓存(SqlSession级别,默认开…

Day38 | 1365. 有多少小于当前数字的数字、941. 有效的山脉数组、1207. 独一无二的出现次数、283. 移动零、189. 轮转数组

1365. 有多少小于当前数字的数字 题目链接&#xff1a;1365. 有多少小、于当前数字的数字 - 力扣&#xff08;LeetCode&#xff09; 题目难度&#xff1a;简单 代码&#xff1a; class Solution {public int[] smallerNumbersThanCurrent(int[] nums) {Map<Integer,Inte…

数据人的进阶之路:四年数仓实践与成长思考

前言 在数据仓库开发的过程中&#xff0c;常常会遇到很多值得思考的问题&#xff0c;它们不仅关乎技术的深度&#xff0c;也涉及业务理解、个人的成长&#xff0c;甚至是数据行业未来的价值。回顾过去的经历&#xff0c;有很多问题反复出现&#xff0c;甚至成为绕不开的课题&am…

大文件分片上传及断点续传实现

使用 支持分片上传及断点续传 前端使用 vue 2 后端使用 springboot 源码在私信

图解AUTOSAR_SWS_IOHardwareAbstraction

AUTOSAR IO硬件抽象层详解 基于AUTOSAR标准的IO硬件抽象层设计与实现指南 目录 1. 概述2. 架构设计 2.1 模块架构概览2.2 内部组件结构2.3 与其他模块的交互接口 3. 状态机 3.1 状态定义3.2 状态转换3.3 状态行为 4. ADC信号处理流程 4.1 初始化流程4.2 转换请求和处理4.3 通知…

Python正则表达式(一)

目录 一、正则表达式的基本概念 1、基本概念 2、正则表达式的特殊字符 二、范围符号和量词 1、范围符号 2、匹配汉字 3、量词 三、正则表达式函数 1、使用正则表达式&#xff1a; 2、re.match()函数 3、re.search()函数 4、findall()函数 5、re.finditer()函数 6…

北京交通大学第三届C语言积分赛

作者有言在先&#xff1a; 题解的作用是交流思路&#xff0c;不是抄作业的。可以把重点放在思路分析上而不是代码上&#xff0c;毕竟每个人的代码风格是不一样的&#xff0c;看别人的代码就跟做程序填空题一样。先看明白思路再看代码。 还有就是&#xff0c;deepseek真的很好用…

机器学习之条件概率

1. 引言 概率模型在机器学习中广泛应用于数据分析、模式识别和推理任务。本文将调研几种重要的概率模型,包括EM算法、MCMC、朴素贝叶斯、贝叶斯网络、概率图模型(CRF、HMM)以及最大熵模型,介绍其基本原理、算法流程、应用场景及优势。 2. EM算法(Expectation-Maximizati…

硬件基础--03_电流

电流 十九世纪初:[电流方向]是指正电荷的移动方向。 后来:对于金属导体&#xff0c;正电荷没移动&#xff0c;其实是电子在移动。 为了定义的统一性[电流方向]仍然定义为正电荷的移动方向 所以:[电流方向]与[电子移动方向]是相反的。 概念:电荷的定向移动&#xff0c;形成了电…

multi paxos协议

1. Redo Log 同步的核心目标 ​数据一致性&#xff1a;确保所有副本在事务提交后具有相同的数据视图。​容错性&#xff1a;在主副本故障时&#xff0c;从副本能快速接管并恢复数据。​高吞吐&#xff1a;通过批量同步和并行处理提升效率。 2. Multi Paxos 协议的同步流程 M…

借壹起航东风,中国工厂出海开启新征程

在经济全球化不断深入的当下&#xff0c;中国工厂正以积极的姿态投身海外市场&#xff0c;渴望在全球商业版图中占据一席之地&#xff0c;绽放独特的光彩。然而&#xff0c;出海之路充满了挑战与艰辛&#xff0c;品牌塑造困难重重、询盘量不稳定、营销成本居高不下等问题&#…