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

news2024/12/24 20:10:25

目录

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

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

括号匹配问题

这个问题我们来看力扣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;
    }

}

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

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

相关文章

如何修改文件的修改日期?

如何修改文件的修改日期&#xff1f;文件的修改日期指的是文件最近一次被修改的日期和时间。当文件内容被修改、编辑或更新时&#xff0c;系统会自动更新文件的修改日期。这个日期记录了文件内容的实际修改时间&#xff0c;可以帮助用户了解文件的更新情况以及文件版本的管理。…

[云原生案例2.2 ] Kubernetes的部署安装 【单master集群架构 ---- (二进制安装部署)】网络插件部分

文章目录 1. Kubernetes的网络类别2. Kubernetes的接口类型3. CNI网络插件 ---- Flannel的介绍及部署3.1 简介3.2 flannel的三种模式3.3 flannel的UDP模式工作原理3.4 flannel的VXLAN模式工作原理3.5 Flannel CNI 网络插件部署3.5.1 上传flannel镜像文件和插件包到node节点3.5.…

2023年度API安全状况详解

随着云计算和移动应用的快速发展&#xff0c;API&#xff08;应用程序接口&#xff09;已成为不可或缺的技术组成部分。然而&#xff0c;API的广泛使用也带来了安全风险。本文将探讨2023年的API安全状况&#xff0c;并介绍了一些应对这些安全挑战的最佳实践。 引言 随着全球互联…

改进YOLOv5:结合ICCV2023|动态蛇形卷积,构建不规则目标识别网络

🔥🔥🔥 提升多尺度、不规则目标检测,创新提升 🔥🔥🔥 🔥🔥🔥 捕捉图像特征和处理复杂图像特征 🔥🔥🔥 👉👉👉: 本专栏包含大量的新设计的创新想法,包含详细的代码和说明,具备有效的创新组合,可以有效应用到改进创新当中 👉👉👉: �…

安装ubuntu-20.04.6-desktop版本、根据ISO文件制作U盘启动盘

前言 本文简述&#xff0c;安装Ubuntu20.04.6的过程&#xff0c;包括制作U盘启动盘、安装。 下载Ubuntu镜像 去官网下载桌面版ubuntu-20.04.6镜像&#xff0c;下载完后文件名是ubuntu-20.04.6-desktop-amd64.iso&#xff0c;这里有个问题amd64.iso能安装在intel处理器的电脑…

计算机网络学习笔记(五):运输层(待更新)

5.1 概述 5.1.1 TCP协议的应用场景 TCP为应用层协议提供可靠传输&#xff0c;发送端按顺序发送&#xff0c;接收端按顺序接收&#xff0c;其间发送丢包、乱序&#xff0c;TCP负责重传和排序。下面是TCP的应用场景。 多次交互&#xff1a;客户端程序和服务端程序需要多次交互才…

ai实景直播矩阵式引流---技术开发搭建(剪辑、矩阵、直播)

目前我们的短视频矩阵剪辑分发系统更新&#xff1a; 无人直播更新&#xff1a; 1、新增文案引流&#xff1a;已接入混元数据大模型&#xff0c;千帆数据大模型&#xff0c;星火数据大模型&#xff0c;盘古数据大模型&#xff0c;通义数据大模型&#xff0c;ChatGPT数据大模型…

muduo源码剖析之TimerQueue类

简介 TimerQueue ​ 通过timerfd实现的定时器功能&#xff0c;为EventLoop扩展了一系列runAt&#xff0c;runEvery&#xff0c;runEvery等函数TimerQueue中通过std::set维护所有的Timer&#xff0c;也可以使用优先队列实现 muduo的TimerQueue是基于timerfd_create实现&#…

Jupyter Notebook 内核似乎挂掉了,它很快将自动重启

报错原因&#xff1a; OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade perfo…

AD教程 (十)Value值的核对

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

推荐一款网络拓扑自动扫描工具

topology-scanner Topology-Scanner是WeOps团队免费开放的一个网络拓扑自动扫描模块&#xff0c;可以自动发现网络设备的类型、网络设备之间的互联 资源下载地址&#xff1a;https://download.csdn.net/download/XMWS_IT/88510697 或 加 薇|信|号吗&#xff1a;xmws-IT 免…

C嘎嘎之类和对象下

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解顺序表和链表的利弊&#xff0c;能在不同的题…

MathType安装激活教程安装后点击exe闪退问题解决

MathType安装 官方下载地址&#xff1a;https://mathtype.org/download/ 1.打开下载好的安装包 2.点击我接受 3.等待。 4.默认C盘路径安装&#xff0c;不要修改&#xff0c;点击确定。 5.等待。 6.点击确定。 7.退出安装&#xff0c;安装完成&#xff01; 8.软件安装后&…

人工智能基础_机器学习020_归一化实战_天池工业蒸汽量项目归一化实战过程_使用sklearn库中的最大最小值归一化和_sklearn库中的Z-score归一化_01---人工智能工作笔记0060

首先我们找到对应的数据,天池蒸汽项目的数据. import pandas as pd 导入文件读取库 import numpy as np 导入数学计算库 df=pd.readcsv(./zhenggi_train.txt,sep=\t) 读取csv文件,这个就是天池的用tab分割的数据 X_train = df . iloc[:,: - 1],我们我们切片,从0列,切片到…

Loki | 数据过期自动删除策略设计

最近使用 Loki 碰到一个比较蛋疼问题&#xff0c;配置日志过期时间&#xff0c;配置这种事情&#xff0c;自然是要参照官方文档了&#xff0c;当时就找到了这个文档&#xff0c;地址&#xff1a; https://github.com/grafana/loki/blob/v1.5.0/docs/operations/storage/retenti…

手写txt模拟数据库简易框架

一.前言 之前学校让我们写控制台饿了么项目&#xff0c;当时进度没有到数据库&#xff0c;所以用的文本文件txt&#xff0c;来模拟数据库的实现&#xff0c;其实本质上就是一个文件读写&#xff0c;但是简单文件读写并不能包含我们想要的功能&#xff0c;例如条件查询&#xff…

【算法秘籍】藏在0和1之间的秘密,助你码出优秀人生

《算法秘籍》双十一 5折购书&#xff0c;就在京东商城 数据结构和算法是计算机科学的基石&#xff0c;是计算机的灵魂&#xff0c;要想成为计算机专业人员&#xff0c;学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学的很多新行业都离…

Discord将切换到临时文件链接以阻止恶意软件传播

导语 Discord是一个广受欢迎的社交平台&#xff0c;但其服务器长期以来一直是恶意活动的温床。为了解决这个问题&#xff0c;Discord决定采取行动&#xff0c;将切换到临时文件链接&#xff0c;以阻止恶意软件的传播。本文将介绍Discord的最新举措&#xff0c;并探讨其对用户安…

C盘清理指南(三)——文件目录更改

各位小伙伴你们好&#xff0c;今天的推送是C盘清理系列的第三期——文件路径更改&#xff0c;分为文件夹路径和软件默认路径两个模块。 一&#xff0e;文件夹路径更改 点击进入C盘&#xff0c;依次点击上方“查看——隐藏的项目”&#xff0c;可以看到C盘中各种隐藏目录。 单击…

kafka微服务学习

消息中间件对比&#xff1a; 1、吞吐、可靠性、性能 Kafka安装 Kafka对于zookeeper是强依赖&#xff0c;保存kafka相关的节点数据&#xff0c;所以安装Kafka之前必须先安装zookeeper Docker安装zookeeper 下载镜像&#xff1a; docker pull zookeeper:3.4.14创建容器 do…