精解括号匹配问题与极致栈设计:揭开最大栈和最小栈的奥秘

目录

    • 括号匹配问题
    • 最小栈
    • 最大栈

最大栈和最小栈是极致栈的两个重要变种。最大栈用于存储当前匹配的最大值,而最小栈用于存储当前匹配的最小值。

括号匹配问题

这个问题我们来看力扣20题的描述:
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false

对于这个题我们有两种解决思路:
1.我们用哈希表把所有符号先存储起来,左边符号作key,右边符号作value。遍历字符串的时候,遇见左边符号就入栈,遇见右边符号就与栈顶的符号进行比较,不匹配就返回false。

 public boolean isValid(String s) {
        //获取字符串长度
        int n = s.length();
        //如果字符串长度为奇数,则返回false
        if (n % 2 == 1) {
            return false;
        }
        //创建一个HashMap,用于存储字符串中的括号
        Map<Character, Character> map = new HashMap<>();
        map.put('[', ']');
        map.put('(', ')');
        map.put('{', '}');
        //创建一个栈,用于存储字符串中的括号
        Stack<Character> stack = new Stack<>();
        //遍历字符串中的每一个字符
        for (int i = 0; i < s.length(); i++) {
            char item = s.charAt(i);
            //如果字符串中的字符在HashMap中存在,则将其压入栈中
            if (map.containsKey(item)) {
                stack.push(item);
            } else {
                //如果栈不为空,则弹出栈顶元素,如果弹出的元素与当前字符串中的字符不匹配,则返回false
                if (stack.isEmpty() == false) {
                    char pop = stack.pop();
                    if (map.get(pop) != item) {
                        return false;
                    }
                } else {
                    return false;
                }

            }

        }
        //如果栈为空,则返回true,否则返回false
        return stack.isEmpty();
    }
  1. 单纯的使用栈,如果遇见左边符号直接压入栈中,遇见右边的符号是先判断栈是否为空,为空则返回false,不为空则弹出栈顶元素,如栈顶元素不为相匹配的左边符号则直接返回false,最后元素遍历完返回栈是否为空。
public boolean isValid(String s) {
        int n = s.length();
        // 如果字符串长度为奇数,则直接返回false
        if (n % 2 == 1) {
            return false;
        }
        // 创建一个栈
        Deque<Character> stack = new LinkedList<>();
        // 遍历字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 如果当前字符为左括号,则将其压入栈中
            if (c == '(' | c == '[' || c == '{') {
                stack.push(c);
            // 如果当前字符为右括号,则从栈中弹出一个元素,如果弹出的元素与当前字符不匹配,则返回false
            } else if (c == '}' || c == ']' || c == ')') {
                if (stack.isEmpty()) {
                    return false;
                }
                char top = stack.pop();
                if ((top != '(' && c == ')') || (top != '{' && c == '}') || (top != '[' && c == ']')) {
                    return false;
                }
            }

        }
        // 如果栈为空,则返回true,否则返回false
        return stack.isEmpty();
    }

最小栈

我们来看力扣155题的描述:
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

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

这个题通俗的理解就是给栈提供一个能获取最小元素的方法并且要在常数时间内。
我们可以设计一个辅助栈,与元素栈同步插入与删除,用于存储每个元素入栈时的最小值(也就是说在辅助栈中我们每次插入的是元素栈中的最小值)
在这里插入图片描述

  • 当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前要入栈的元素中的最小值插入辅助栈中。
  • 当一个元素要出栈时,我们把辅助栈的栈顶元素也一并弹出。
    我们来看具体实现代码:
class MinStack {
    // 定义两个双端队列,分别存放输入的值和当前的最小值
    Deque<Integer> xStack;
    Deque<Integer> minStack;

    public MinStack() {
        // 初始化双端队列
        xStack = new LinkedList<>();
        minStack = new LinkedList<>();
        // 第一个最小值设置为最大值
        minStack.push(Integer.MAX_VALUE);
    }

    public void push(int val) {
        // 输入一个值
        xStack.push(val);
        // 将当前的最小值和输入的值比较,取较小的值
        minStack.push(Math.min(minStack.peek(), val));
    }

    public void pop() {
        // 弹出双端队列的最后一个值
        xStack.pop();
        minStack.pop();
    }

    public int top() {
        // 返回双端队列的最后一个值
        return xStack.peek();
    }

    public int getMin() {
        // 返回双端队列的最小值
        return minStack.peek();
    }
}

最大栈

跟最小栈实现方法类似寻找最大值。
需要注意的就是最后一个方法,弹出最大值,具体就是拿到最大元素,然后在数字栈中把最大值以上的元素全部弹出存储在新建的栈中,然后弹出最大值,最后把新建的栈中的元素重新压入数字栈中。
由于力扣最大栈是VIP题目,我们可以尝试一下牛客的最大栈问题。

class MaxStack {
    // 定义两个栈,一个用来存储数字,另一个用来存储最大值
    Deque<Integer> xStack;
    Deque<Integer> maxStack;

    public MaxStack() {
        // 初始化两个栈
        xStack = new LinkedList<>();
        maxStack = new LinkedList<>();

    }

    public void push(int val) {
        // 获取当前最大值,如果栈为空,则最大值为当前值
        int max = maxStack.isEmpty() ? val : maxStack.peek();
        // 比较当前值和最大值,取最大值
        max = max > val ? max : val;
        // 将值和最大值分别压入栈中
        xStack.push(val);
        maxStack.push(max);
    }

    public int pop() {

        // 弹出最大值栈顶元素
        maxStack.pop();
        // 弹出数字栈顶元素
        return xStack.pop();
    }

    public int top() {
        // 返回数字栈顶元素
        return xStack.peek();
    }

    public int peekMax() {
        // 返回最大值栈顶元素
        return maxStack.peek();
    }

    public int popMax() {
        // 获取最大值栈顶元素
        int max = peekMax();
        // 创建一个栈
        Stack<Integer> stack = new Stack<>();
        // 当栈顶元素不等于最大值时,将栈顶元素压入栈中
        while (top() != max) {
            stack.push(pop());
        }
        // 弹出数字栈顶元素
        pop();
        // 将栈中的元素弹出,压入数字栈中
        while (!stack.isEmpty()) {
            push(stack.pop());
        }
        // 返回最大值
        return max;
    }

}

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

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

相关文章

大数据毕业设计选题推荐-营业厅营业效能监控平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

RTC实时时钟——DS1302

DS1302目录 一、DS1302简介引脚定义与推荐电路 二、芯片手册1.操作寄存器的定义2.时序定义dc1302.cds1302.h 三、蓝桥杯实践 一、DS1302简介 RTC(Real Time Clock):实时时钟&#xff0c;是一种集成电路&#xff0c;通常称为时钟芯片。现在流行的串行时钟电路很多&#xff0c;如…

把wpf的窗体保存为png图片

昨晚在stack overflow刷问题时看到有这个问题&#xff0c;今天早上刚好来尝试学习一下 stack overflow的链接如下&#xff1a; c# - How to render a WPF UserControl to a bitmap without creating a window - Stack Overflow 测试步骤如下&#xff1a; 1 新建.net frame…

企业微信vs个人微信:对比对照一览表

继微信后&#xff0c;腾讯推出了企业微信。企业微信可以添个人微信为好友&#xff0c;有群聊和朋友圈&#xff0c;粗看起来与个人微信十分相似&#xff0c;那么它们有什么区别呢&#xff1f; 企业微信和个人微信的区别是什么&#xff0c;咱今天两张图来对比看看~

输电线路AR可视化巡检降低作业风险

随着现代工业的快速发展&#xff0c;各行业的一线技术工人要处理的问题越来越复杂&#xff0c;一些工作中棘手的问题迫切需要远端专家的协同处理。但远端专家赶来现场往往面临着专家差旅成本高、设备停机损失大、专业支持滞后、突发故障无法立即解决等痛点。传统的远程协助似乎…

数据结构与算法-(11)---有序表(OrderedList)

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:PYTHON学习系列专栏 &#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 知识回顾及总结 有序表的引入 ​编辑 实现有序表 1.有序表-类的构造方法 2.有序表-search方法的实现 3.有序表-add方法的实现…

勒索病毒最新变种.halo勒索病毒来袭,如何恢复受感染的数据?

导言&#xff1a; 在当今数字化时代&#xff0c;网络犯罪分子不断进化&#xff0c;勒索病毒已经成为一种广泛传播的网络威胁。本文91数据恢复将深入介绍.halo勒索病毒&#xff0c;包括它的工作原理、如何从中恢复被加密的数据文件以及如何采取预防措施来保护自己免受感染。当面…

AD教程 (十)Value值的核对

AD教程 &#xff08;十&#xff09;Value值的核对 填写器件位号 直接根据原理图的原始编号进行更改 通过位号编辑器快速更改 点击工具&#xff0c;选择标注&#xff0c;选择原理图标注&#xff0c;进入位号编辑器 可以在位号编辑器中 设置处理顺序&#xff0c;从上往下还是从…

基于Skywalking的全链路跟踪实现

在前文“分布式应用全链路跟踪实现”中介绍了分布式应用全链路跟踪的几种实现方法&#xff0c;本文将重点介绍基于Skywalking的全链路实现&#xff0c;包括Skywalking的整体架构和基本概念原理、Skywalking环境部署、SpringBoot和Python集成Skywalking监控实现等。 1、Skywalki…

C#中的DataTable使用

在C#中&#xff0c;DataTable 是一个非常重要的组件&#xff0c;它是System.Data命名空间下的一部分。它用于在内存中存储表格数据&#xff0c;可以看作是一个内存中的数据库表。以下是DataTable的一些主要特点和常用的操作&#xff1a; 特点 内存中的数据存储&#xff1a;Da…

java入坑之类加载器

一、类加载机制 1.1类加载过程 类加载是Java虚拟机将类的字节码数据从磁盘或网络中读入内存&#xff0c;并转换成在JVM中可以被执行的Java类型的过程。类加载器是Java虚拟机的重要组成部分&#xff0c;负责加载和解析类的字节码&#xff0c;将其转换成Java虚拟机中的类对象&am…

14 http协议详解

1、http是应用层协议 统一资源定位符&#xff1a; 例如 http://www.jd.com是个URL&#xff0c;http是协议&#xff0c;www.jd.com是域名&#xff0c;表示互联网上的一个位置&#xff0c;有些url的资源定位会更清晰&#xff0c;比如http://www.jd.com/index.html 2、HTTP 请求…

【Solidity】Solidity中的基本数据类型和复合数据类型

1. 基本数据类型 1.1 整数类型 Solidity支持有符号整数和无符号整数&#xff0c;可以指定位数和范围。以下是一些整数类型的示例&#xff1a; int&#xff1a;有符号整数&#xff0c;可以是正数或负数。2&#xff0c;-45&#xff0c;2023 uint&#xff1a;无符号整数&#x…

TLS回调函数

TLS在逆向中的作用 TLS回调函数常用于反调试 TLS先于EP代码执行 TLS是什么 TLS是各线程的独立的数据存储空间 使用TLS技术可以在线程内部独立使用或修改进程的全局数据或静态数据 创建和终止某进程时&#xff0c;TLS回调函数都会自动调用执行 使用OD调试TLS函数

云尘靶场 --JIS-CTF-VulnUpload

重新下vpn连接的文件 还是fscan扫 访问一下13 到了/login.php 随便弱口令试试 好吧没成功&#xff0c;那目录扫描一下 那就先看一下robots.txt了 flag有点快的 抱着试一试的态度看一下admin_area 没想到源代码里面居然有 这么这么多 本来还以为密码要去爆破的&#xff0…

刚柔相济铸伟业 ——访湖南顺新金属制品科技有限公司董事长张顺新

时代在变&#xff0c;唯初心不改。 精致、谦虚、谨慎、儒雅、温和——他就是张顺新&#xff0c;湖南顺新金属制品科技有限公司、湖南顺新供应链管理有限公司董事长&#xff0c;民建长沙市委常委&#xff0c;民建湖南省环资委副主任&#xff0c;省、市民建企联会常务副会长&…

大文件传输小知识 | UDP和TCP哪个传输速度快?

在网络世界中&#xff0c;好像有两位“传输巨头”常常被提起&#xff1a;UDP和TCP。它们分别代表着用户数据报协议和传输控制协议。那么它们是什么&#xff1f;它们有什么区别&#xff1f;它们在传输大文件时的速度又如何&#xff1f;本文将深度解析这些问题&#xff0c;帮助企…

大数据Doris(十九):数据导入(Load)

文章目录 数据导入(Load) 一、Broker load 二、Stream load 三、Insert 四、Multi load

10 DETR 论文精读【论文精读】End-to-End Object Detection with Transformers

目录 DETR 这篇论文&#xff0c;大家为什么喜欢它&#xff1f;为什么大家说它是一个目标检测里的里程碑式的工作&#xff1f;而且为什么说它是一个全新的架构&#xff1f; 1 题目 2摘要 2.1新的任务定义&#xff1a;把这个目标检测这个任务直接看成是一个集合预测的问题 2.…

博途PLC增量式PID(支持正反作用和归一化输出)

博途PLC增量式PID算法详细介绍请参考下面文章链接: 【精选】博途1200/1500PLC增量式PID算法(详细SCL代码)_西门子博途pid csdn_RXXW_Dor的博客-CSDN博客文章浏览阅读3.4k次,点赞2次,收藏12次。SMART200PLC增量式PID可以参看下面这篇博文,文章里有完整的增量式PID算法公式,…