【数据结构练习题】栈——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<>();
    //push
    public void push(int val) {
        //普通栈直接压栈
        stack.push(val);
        //最小栈压栈两种情况
        if(Minstack.empty()) {
            //1.最小栈为空栈,直接压栈。
            Minstack.push(val);
        }
        else {
            //2.最小栈不为空栈,则需要将压栈的元素与最小栈栈顶元素比较,当压栈元素<=最小栈栈顶元素则可以压栈
            if(val <= Minstack.peek()) {
                Minstack.push(val);
            }
        }
    }
    //pop
    public void pop() {
        int ret = stack.pop();
        if (ret == Minstack.peek()) {
            Minstack.pop();
        }
    }
    //peek
    public int peek() {
       return stack.peek();
    }
    //getMin
    public 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());
    }
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

金融知识分享系列之:MACD指标精讲

金融知识分享系列之&#xff1a;MACD指标精讲 一、MACD指标二、指标原理三、MACD指标参考用法四、MACD计算步骤五、MACD分析要素六、根据快线DIF位置判断趋势七、金叉死叉作为多空信号八、快线位置交叉信号九、指标背离判断行情反转十、差离值的正负十一、差离值的变化十二、指…

KBP210-ASEMI新能源专用整流桥KBP210

编辑&#xff1a;ll KBP210-ASEMI新能源专用整流桥KBP210 型号&#xff1a;KBP210 品牌&#xff1a;ASEMI 封装&#xff1a;KBP-4 正向电流&#xff08;Id&#xff09;&#xff1a;2A 反向耐压&#xff08;VRRM&#xff09;&#xff1a;1000V 正向浪涌电流&#xff1a;6…

中整协与成都艺星联合主办的“面部馒化修复注射技术培训班”圆满落下帷幕

在追求医疗美容学科深度的道路上&#xff0c;Yestar成都艺星再次成为行业先锋&#xff0c;近日&#xff0c;由中整协与成都艺星整形美容医院联合主办的“面部馒化修复注射技术培训班”在Yestar成都艺星圆满落下帷幕。本次培训班以其严谨的学术精神和对临床治疗思路的深入解读&a…

在idea中配置tomcat服务器,部署一个项目(下载教程加链接)

第一步&#xff1a;把Tomcat下载好 ww​​​​​​​Apache Tomcat - Welcome! 链接如上&#xff1a;进去后在左边找到Tomcat8点击进去后 找到图下内容 第二步&#xff1a; 打开这个文件点击bin进去 会出现一个黑色框框&#xff0c;也就是服务器 完成后就可以在浏览器输入…

Redis 搭建主从集群

文章目录 1. 主从集群架构1.1 准备实例和配置1.2 启动1.3 开启主从关系1.4 测试 2. 主从同步原理2.1 全量同步2.2 增量同步repl_backlog原理 2.3 主从同步优化小结 单节点的 Redis 并发能力有限&#xff0c;要进一步提高 Redis 的并发能力&#xff0c;就需要搭建主从集群&#…

2024年无人直播是否已经成为新趋势,商家使用矩图AI无人直播月增长5万+

无论是 个体商户、企业经营者、电商从业者、想创业赚钱的朋友;也不管你是做餐饮还是非餐饮;亦或是抖音小时达外卖。这篇文章&#xff0c;请勿必看完&#xff0c;对你的业绩增长是有绝对的帮助。 无人直播的发展经历了几个时代&#xff0c;现在已经到了4.0的时代&#xff0c;更安…

刷题DAY24 | LeetCode 77-组合

1 回溯法理论基础 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 所以以下讲解中&#xff0c;回溯函数也就是递归函数&#xff0c;指的都是一个函数。 1.1 回溯法的效率 回溯法的性能如何呢&#xff0…

深入探索Java并发编程:ArrayBlockingQueue详解

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在Java的并发编程世界中&#xff0c;java.util.concurrent包为我们提供了多种用于线程间安全通信的数据结构&#xff0c;其中Arra…

PTA冰岛人

作者 陈越 单位 浙江大学 2018年世界杯&#xff0c;冰岛队因1:1平了强大的阿根廷队而一战成名。好事者发现冰岛人的名字后面似乎都有个“松”&#xff08;son&#xff09;&#xff0c;于是有网友科普如下&#xff1a; 冰岛人沿用的是维京人古老的父系姓制&#xff0c;孩子的姓…

【研发日记】Matlab/Simulink技能解锁(二)——在Matlab Function编辑窗口Debug

文章目录 前言 行断点 条件断点 按行步进 Watch Value 分析和应用 总结 前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 行断点 当Matlab Function出现异常时&#xff0c;如果能确定大致的代码段&#xff0c;就可以在相应的行上设置一…

为什么单线程的 Redis 能那么快?

大家好我是苏麟 , 给大家找一些好的文章看看 . 原文文章 : 03 高性能IO模型&#xff1a;为什么单线程Redis能那么快&#xff1f; (lianglianglee.com) Redis 为什么用单线程&#xff1f; 要更好地理解 Redis 为什么用单线程&#xff0c;我们就要先了解多线程的开销。 多线程的…

算法打卡day18|二叉树篇07|Leetcode 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

算法题 Leetcode 530.二叉搜索树的最小绝对差 题目链接:530.二叉搜索树的最小绝对差 大佬视频讲解&#xff1a;二叉搜索树的最小绝对差视频讲解 个人思路 因为是在二叉搜索树求绝对差&#xff0c;而二叉搜索树是有序的&#xff0c;那就把它想成在一个有序数组上求最值&…

CVE-2019-5782:kArgumentsLengthType 设置偏小导致优化阶段可以错误的去除 CheckBound 节点

文章目录 环境搭建漏洞分析笔者初分析笔者再分析漏洞触发源码分析 漏洞利用总结 环境搭建 sudo apt install pythongit reset --hard b474b3102bd4a95eafcdb68e0e44656046132bc9 export DEPOT_TOOLS_UPDATE0 gclient sync -D// debug version tools/dev/v8gen.py x64.debug ni…

分布式调用与高并发处理(二)| Dubbo

文章目录 Dubbo概念_什么是分布式系统单机架构集群架构分布式架构单机、集群和分布式的区别 Dubbo概念_什么是RPCRPC两个作用&#xff1a;常见 RPC 技术和框架&#xff1a; Dubbo概念_简介Dubbo能做什么Dubbo支持的协议 Dubbo概念_核心组件注册中心Registry服务提供者Provider服…

Cartwheel——文本生成3D动作或动画的工具

一个强大的文本转3D动画平台,用户只需通过输入文字提示即可生成视频、游戏、电影、广告、社交或VR项目所需的3D动画角色。 Cartwheel 是一个功能强大的文本到动画平台。只需键入即可为您的视频、游戏、电影、广告、社交或 VR 项目制作角色动画 定位: 定位于为用户提供简单…

Java学习笔记(13)

阶段项目 拼图小游戏 JFrame JMenuBar JMenu JMenuItem 用add方法添加到不同的对象中 添加图片 先创建一个图片ImageIcon的对象&#xff0c;写入图片的路径 再创建JLabel管理容器对象&#xff0c;把图片放到这个容器中&#xff0c;再把容器添加到界面 界面坐标位置 改变图…

MySQL数据导入的方式介绍

MySQL数据库中的数据导入是一个常见操作&#xff0c;它涉及将数据从外部源转移到MySQL数据库表中。在本教程中&#xff0c;我们将探讨几种常见的数据导入方式&#xff0c;包括它们的特点、使用场景以及简单的示例。 1. 命令行导入 使用MySQL命令行工具mysql是导入数据的…

pycharm @NotNull parameter ‘module‘ of ...

下载了最新pycharm &#xff0c;无法启动运行 pycharm或者idea中Run/Debug Python项目报错 Argument for NotNull parameter ‘module‘ of … 解决方案 删除项目根目录的 idea 文件夹 随后重启&#xff0c;重新配置即可

vue项目中使用highcharts记录(甘特图)

使用npm添加到项目中&#xff1a; npm install highcharts npm install highcharts-vue// 我在实际使用时用上面两条命令安装后&#xff0c;引入时会报错 // 所以按照下面的示例中的版本安装的指定版本(vue版本为2.6.14)npm install highcharts7.1.3 npm install highchart…

计算机考研|跨专业考408到底有多难?

在就是说&#xff0c;敢跨专业考研的&#xff0c;都是狠人 为什么这么说&#xff0c;因为考研备考最多也就一年的时间&#xff0c;然后还要处理自己本专业的事情&#xff0c;还要学习心得&#xff0c;从来没有接触过的专业课&#xff0c;那真的就是抓瞎啊。这绝对要很强的时间…