【数据结构练习题】栈——1.括号匹配 2.逆波兰表达式求值 3.出栈入栈次序匹配 4.最小栈

在这里插入图片描述
♥♥♥♥♥个人主页♥♥♥♥♥
♥♥♥♥♥数据结构练习题总结专栏♥♥♥♥♥

文件目录

  • 前言
    • 1.括号匹配
    • 1.1问题描述
    • 1.2解题思路
    • 1.3画图解释
    • 1.4代码实现
      • 2.逆波兰表达式求值
    • 2.1问题描述
    • 2.2解题思路
    • 2.3画图解释
    • 2.4代码解释
        • 3.出栈入栈次序匹配
    • 3.1问题描述
    • 3.2思路分析
    • 3.3画图解释
    • 3.4代码实现
          • 4.最小栈
    • 4.1问题描述
    • 4.2思路分析
    • 4.3画图分析
    • 4.4代码实现

前言

在学习数据结构的过程中遇到了各种各样类型的题目,我在解答这些题目的时候收获了不少,所以我想开设一个专栏来分享我平时做题的收获,在我分享的题中我采用三步法来阐述,希望大家可以在我的文章有收获,并且能够在评论区中积极讨论更多的解题方法。

1.括号匹配

1.1问题描述

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
3.每个右括号都有一个对应的相同类型的左括号

1.2解题思路

大主题:我们先遍历这个字符串,在遇到左括号就进行压栈,遇到右括号则出栈并与左括号匹配,在这会出现两种情况:
1.如果不匹配,则直接返回false。
2.如果匹配,则可以继续去遍历这个字符串。
特殊情况:
1.当遍历完字符串,发现栈中还有元素,则可以直接返回false。
2.当栈中的元素已经全部被弹出,发现字符串没有被遍历完,也直接返回false。

1.3画图解释

1.大主题:
在这里插入图片描述
2.特殊情况:
在这里插入图片描述

1.4代码实现

public class ParenMatch {Stack<Character> stack = new Stack<>();public boolean isValid(String str) {//1.遍历这个数组for (int i = 0; i < str.length(); i++) {//2.判断是左括号还是右括号char ch = str.charAt(i);//2.1左括号if(ch == '(' || ch == '[' || ch == '{' ) {//压栈stack.push(ch);}//2.2右括号 看栈中是否为空,为空直接返回flase 不为空判断左右括号是否匹配。else {//2.2.1栈中不为空if(!stack.empty()) {char ch1 = stack.peek();//ch1是左括号。//判断括号是否匹配if(ch == ')' && ch1 == '(' || ch == ']' && ch1 == '[' || ch == '}' && ch1 == '{') {stack.pop();}else {return false;}}//2.2.2栈中为空else {return false;}}}//当数组遍历完之后,判断栈中是否空。return stack.empty();}public static void main(String[] args) {String str = "{()}";ParenMatch parenMatch = new ParenMatch();System.out.println(parenMatch.isValid(str));}
}

2.逆波兰表达式求值

2.1问题描述

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用 32 位 整数表示。

2.2解题思路

在解决这个问题,我先解释什么叫逆波兰表达式,其实它有个更好理解的一个名字叫后缀表达式,我们既然提到了后缀表达式,那估计也有一些人不知道后缀表达式是什么?那我们就需要引出中缀表达式来了解后缀表达式。
其实中缀表达式就是我们平时经常可以见到的一个表达式,它就是将运算符放在数字之间的一种表达式如:a+(b+c)+d*(e+f)这种类型的就叫中缀表达式,而后缀表达式其实就是将运算符放在数字的后面。我就用a+(b+c)+d*(e+f)这个来打比方,将它转化为后缀表达式。
中缀表达式转后缀表达式分三步:
第一步:加括号,从左到右先乘除后加减去加括号。
在这里插入图片描述
第二步:将运算符移到每个对应括号的外面
在这里插入图片描述
第三步:再将所有的括号全部删除,得到的就是后缀表达式
在这里插入图片描述
既然得到了后缀表达式,那我们运用栈来求这个表达式的值。
我们先将这个表达式看作一个字符串,然后我们再采用遍历的方法去一个一个的去遍历这个字符串,我采取的规则是遇到除运算符的任何元素压入栈中,遇到运算符则从栈中弹出两个元素,分别放在运算符的右侧和左侧(这里的左右很重要,因为运算符如果是除法或者减法,运算符的左右侧元素不同那么结果是不一样)得到的结果压入栈中,直到字符串遍历完之后,最后留在栈中的值就是这个表达式的值。

2.3画图解释

在这里插入图片描述

2.4代码解释

public class evalRPN {String[] tokens = {"2","1","+","3","*"};Stack<Integer> stack = new Stack<>();public int  ergodic() {//遍历这个数组for (int i = 0; i < tokens.length; i++) {//判断字符串是否为运算符字符串String str = tokens[i];if(!isOperator(str)) {//字符串为数字,说明将这个字符串数字先转化为数字再压入栈中int ret = Integer.valueOf(str);stack.push(ret);}else {//字符串为运算符int rightNum = stack.pop();int leftNum = stack.pop();switch (str) {case "+":stack.push(leftNum+rightNum);break;case "-":stack.push(leftNum-rightNum);break;case "*":stack.push(leftNum*rightNum);break;case "/":stack.push(leftNum/rightNum);break;}}}return stack.pop();}private boolean isOperator(String str) {if(str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") ) {return true;}return false;}public static void main(String[] args) {evalRPN evalRPN = new evalRPN();System.out.println(evalRPN.ergodic());}
}
3.出栈入栈次序匹配

3.1问题描述

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

3.2思路分析

1.先去遍历第一个数组,每遍历到数组每一个元素先与压入栈中再看栈顶元素与另一个数组的第一个元素进行比较。
2.相同则弹出,并且第二个数组往后遍历反之第一个数组继续遍历并且压入栈中。
3.直到栈为空或者第一个数组遍历完。

3.3画图解释

在这里插入图片描述

3.4代码实现

public class PushPopMatch {Stack<Integer> stack = new Stack<>();public boolean IsPopOrder (int[] pushV, int[] popV) {int j =0;for (int i = 0; i < pushV.length; i++) {//1.压入栈中stack.push(pushV[i]);//2.将栈顶元素与popV数组比较,相同则弹出并且j++,反之继续压栈。//当这个条件stack.peek() == popV[j]出来了,你需要确保栈不能为空并且数组不能越界。while(j<popV.length &&!stack.empty() && stack.peek() == popV[j]) {stack.pop();j++;}}return stack.empty();}public static void main(String[] args) {int[] pushA = {1,2,3,4,5};int[] popA = {4,5,3,2,1};PushPopMatch pushPopMatch = new PushPopMatch();System.out.println(pushPopMatch.IsPopOrder(pushA, popA));}
}
4.最小栈

4.1问题描述

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

4.2思路分析

我们先想一想,一个栈可以完成这个目标吗?,明显的是不能满足时间复杂度,所以我们需要两个栈来解决这个问题,我们创建一个普通栈和一个最小栈。
1.实现push操作:普通栈每一个元素都需要压栈,但最小栈有两种情况:
情况1:最小栈是空栈,那么第一个元素直接压入最小栈
情况2:最小栈不是空栈,则需要将压栈的元素与最小栈的栈顶元素进行比较,当满足压栈元素<=最小栈栈顶元素则压栈
2. 实现pop操作:普通栈每一个元素都可以出栈,但最小栈有两种情况:
情况1:普通栈出栈的元素与最小栈的栈顶元素相同则都弹出
情况2:普通栈出栈的元素与最小栈的栈顶元素不相同,则普通栈弹出,最小栈不要弹出。
3.实现top操作:直接弹出普通栈的栈顶的元素。
4.实现getMin操作:直接弹出最小栈的栈顶元素

4.3画图分析

1.实现push操作:
在这里插入图片描述

2.实现pop操作:

在这里插入图片描述

4.4代码实现

public class GetMinStack {Stack<Integer> stack= new Stack<>();Stack<Integer> Minstack= new Stack<>();//pushpublic void push(int val) {//普通栈直接压栈stack.push(val);//最小栈压栈两种情况if(Minstack.empty()) {//1.最小栈为空栈,直接压栈。Minstack.push(val);}else {//2.最小栈不为空栈,则需要将压栈的元素与最小栈栈顶元素比较,当压栈元素<=最小栈栈顶元素则可以压栈if(val <= Minstack.peek()) {Minstack.push(val);}}}//poppublic void pop() {int ret = stack.pop();if (ret == Minstack.peek()) {Minstack.pop();}}//peekpublic int peek() {return stack.peek();}//getMinpublic int getMin() {return Minstack.peek();}public static void main(String[] args) {GetMinStack getMinStack = new GetMinStack();getMinStack.push(-2);getMinStack.push(0);getMinStack.push(-3);System.out.println(getMinStack.getMin());}
}

结尾:希望大家可以给我点点关注,点点赞,并且在评论区发表你们的想法和意见,我会认真看每一条评论,你们的支持就是我的最大鼓励。🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹

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

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

相关文章

【No.13】蓝桥杯二分查找|整数二分|实数二分|跳石头|M次方根|分巧克力(C++)

二分查找算法 知识点 二分查找原理讲解在单调递增序列 a 中查找 x 或 x 的后继在单调递增序列 a 中查找 x 或 x 的前驱 二分查找算法讲解 枚举查找即顺序查找&#xff0c; 实现原理是逐个比较数组 a[0:n-1] 中的元素&#xff0c;直到找到元素 x 或搜索整个数组后确定 x 不在…

CPU设计实战—异常处理指令

异常类型以及精确异常的处理 异常有点像中断&#xff0c;处理完还要回到原来的状态&#xff0c;所以需要对之前的状态进行保存。本CPU主要实现对以下异常的处理&#xff1a; 1.外部硬件中断 2.复位异常 3.系统调用异常&#xff08;发生在译码阶段&#xff09; 4.溢出异常&…

做好外贸网站SEO优化,拓展海外市场

随着全球贸易的发展和互联网的普及&#xff0c;越来越多的外贸企业将目光投向了网络&#xff0c;希望通过建立网站来拓展海外市场。然而&#xff0c;在竞争激烈的外贸市场中&#xff0c;要让自己的网站脱颖而出&#xff0c;吸引更多的目标客户&#xff0c;就需要进行有效的SEO优…

openGauss学习笔记-246 openGauss性能调优-SQL调优-经验总结:SQL语句改写规则

文章目录 openGauss学习笔记-246 openGauss性能调优-SQL调优-经验总结&#xff1a;SQL语句改写规则246.1 使用union all代替union246.2 join列增加非空过滤条件246.3 not in转not exists246.4 选择hashagg246.5 尝试将函数替换为case语句246.6 避免对索引使用函数或表达式运算2…

面试算法-50-二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 解 class Solution {public int maxDepth(TreeNo…

《算法设计与分析第二版》100行 C语言实现 广度度优先算法 BFS——最短距离

抄录自课本P157页。 #include <stdio.h> #define MAXQ 100 // 队列大小 #define MAxN 10 // 最大迷宫大小 int n8; // 迷宫大小 char Maze [MAxN][MAxN] {{O,X,X,X,X,X,X,X,},{O,O,O,X,O,X,O,X,},{X,X,O,O,O,X,O,X,},{X,X,O,X,O,X,X,X,},…

HDFS概述及常用shell操作

HDFS 一、HDFS概述1.1 HDFS适用场景1.2 HDFS优缺点1.3 HDFS文件块大小 二、HDFS的shell操作2.1 上传2.2 下载2.3 HDFS直接操作 一、HDFS概述 1.1 HDFS适用场景 因为HDFS里所有的文件都是维护在磁盘里的 在磁盘中对文件的历史内容进行修改 效率极其低(但是追加可以) 1.2 HDF…

走近 AI Infra 架构师:在高速飞驰的大模型“赛车”上“换轮子”的人

如果把大模型训练比作 F1 比赛&#xff0c;长凡所在的团队就是造车的人&#xff0c;也是在比赛现场给赛车换轮子的人。1% 的训练提速&#xff0c;或者几秒之差的故障恢复时间&#xff0c;累积起来&#xff0c;都能影响到几百万的成本。长凡说&#xff1a;“大模型起来的时候&am…

算法详解——选择排序和冒泡排序

一、选择排序 选择排序算法的执行过程是这样的&#xff1a;首先&#xff0c;算法遍历整个列表以确定最小的元素&#xff0c;接着&#xff0c;这个最小的元素被置换到列表的开头&#xff0c;确保它被放置在其应有的有序位置上。接下来&#xff0c;从列表的第二个元素开始&#x…

事件高级、

文章目录 1.注册事件&#xff08;绑定事件&#xff09;addEventListener 事件监听方式attachEvent 事件监听方式、兼容性解决方案 * 2.删除事件&#xff08;解绑事件&#xff09;删除事件的方式删除事件兼容性解决方案 * 3.DOM事件流4.事件对象使用语法兼容性方案*常见属性和方…

边缘计算+WEB端应用融合:AI行为识别智能监控系统搭建指南 -- 边缘设备图像识别及部署(二)

专栏目录 边缘计算WEB端应用融合&#xff1a;AI行为识别智能监控系统搭建指南 – 整体介绍&#xff08;一&#xff09; 边缘计算WEB端应用融合&#xff1a;AI行为识别智能监控系统搭建指南 -- 边缘图像识别及部署&#xff08;二&#xff09; 前言边缘图像识别与推流整体思路原始…

海康威视添加新摄像头到原建的网络监控平台中

一、适用场景 1、企业已经存在一套海康威视的监控网络系统&#xff1b; 2、根据业务的需求&#xff0c;要新增加一些摄像头&#xff1b; 3、原施工方忙碌&#xff0c;为新增加的摄像头施工成本较高&#xff1b; 4、新增加海康威视的摄像头视频监控&#xff0c;保存在原建的监控…

构建强大的API:Django中的REST框架探究与实践【第146篇—Django】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 构建强大的API&#xff1a;Django中的REST框架探究与实践 在当今的Web开发中&#xff0c;构…

Apache SeaTunnel MongoDB CDC 使用指南

随着数据驱动决策的重要性日益凸显&#xff0c;实时数据处理成为企业竞争力的关键。SeaTunnel MongoDB CDC(Change Data Capture) 源连接器的推出&#xff0c;为开发者提供了一个高效、灵活的工具&#xff0c;以实现对 MongoDB 数据库变更的实时捕获和处理。 本文将深入探讨该连…

Jackson 2.x 系列【1】概述

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 前言2. 什么是 JSON3. 常用 Java JSON 库4. Jackson4.1 简介4.2 套件4.3 模块4.…

prompt开发生命周期

1.定义任务场景和成功标准 任务场景可分为简单任务&#xff1a;实体抽取、qa等 复杂任务&#xff1a;代码生成、创意写作等 在定义任务后&#xff0c;就要定义模型实现该任务的成功标准&#xff1a; 模型表现和准确率&#xff1b;延迟&#xff1b;价格。 2.开发测试用例 多…

Vue2(七):超详细vue开发环境搭建(win7),nodejs下载与安装,安装淘宝镜像(报错已解决),配置脚手架

一、安装node.js 本来想粗略写一下的&#xff0c;但是搭建脚手架的时候&#xff0c;遇到了很多问题&#xff0c;浪费快两天时间&#xff0c;记录一下自己的解决办法希望对你们有帮助&#xff01; 1.下载nodejs 安装包下载链接【CNPM Binaries Mirror】 下载我划线的这个&am…

代码随想录算法训练营第25天| 216.组合总和III、17.电话号码的字母组合

216.组合总和III 题目链接&#xff1a;组合总和III 题目描述&#xff1a;找出所有相加之和为 n **的 k ****个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c…

2024热门外贸独立站wordpress模板

工艺品wordpress外贸主题 简约大气的wordpress外贸主题&#xff0c;适合做工艺品进出品外贸的公司官网使用。 https://www.jianzhanpress.com/?p5377 日用百货wordpress外贸主题 蓝色大气的wordpress外贸主题&#xff0c;适合做日用百货的外贸公司搭建跨境电商网站使用。 …

Qt教程 — 3.3 深入了解Qt 控件:Input Widgets部件(2)

目录 1 Input Widgets简介 2 如何使用Input Widgets部件 2.1 QSpinBox组件-窗口背景不透明调节器 2.2 DoubleSpinBox 组件-来调节程序窗口的整体大小 2.3 QTimeEdit、QDateEdit、QDateTimeEdit组件-编辑日期和时间的小部件 Input Widgets部件部件较多&#xff0c;将分为三…