vb6 判断打印机是否有效_吊打面试官 | 算法之如何判断括号是否有效?

b187109579d820cdabbef48316036231.png

今天要讲的这道题是 bilibili 今年的笔试真题,也是一道关于栈的经典面试题。

经过前面文章的学习,我想很多朋友已经看出来了,我接下来要写的是一个关于「算法图解」的系列文章,中间可能会穿插少量的其他类型的文章,但「算法和数据结构」会是我今年文章输出的重点内容。

我在写这个算法系列的时候会注意两个问题:

  • 保证算法的解题思路大家都能看懂,因此我会以图片的形式进行思路讲解,这样更直观、更易于理解
  • 在介绍完一个知识点之后,会进行大量的练习,以巩固所学的内容,比如当我讲完「栈」结构之后,我会围绕着「栈」做一系列的经典面试题练习。

学习算法最关键的是掌握解题的思路,只要思路对了,编写代码只是时间的问题。

我们先来回顾一下往期关于「栈」的内容:

  • 《动图演示:手撸堆栈的两种实现方法!》
  • 《JDK 竟然是这样实现栈的?》
  • 《链表反转的两种实现方法,后一种击败了100%的用户!》
  • 《算法图解:如何找出栈中的最小值?》

那么接下来,我们就进入今天的正式内容...

题目

给定一个只包括 '(', ')', '{', '}', '[', ']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"

输出: true

示例 2:

输入: "()[]{}"

输出: true

示例 3:

输入: "(]"

输出: false

示例 4:

输入: "([)]" 输出: false

示例 5:

输入: "{[]}"

输出: true

LeetCode 地址:https://leetcode-cn.com/problems/valid-parentheses

解题思路

这道题考察的是就是验证括号的对称性,比如“([{}])”这种字符串就是正确的,应该返回 true,而“([{})]”这种字符串就是错误的,应该返回 false。

从上面的题目可以看出,括号总共分为三类:小括号、中括号和大括号,那么我们可以利用栈先进后出的特性,将所有左边的括号(“(”、“[”、“{”)先入栈,然后再碰到右括号时,让它与栈顶的元素进行匹配,比如当遇到“)”时,如果栈顶是“(”,则说明匹配成功,栈顶元素出栈再继续字符串循环的流程,如果匹配错误就直接返回 false。

假设我们要匹配字符串“(([]))”是否合法?那么执行流程就是这样的。

首先遇到左边括号,先入栈:

f6c92dbe0004dc197857ce92d5961afc.png

接下来又是左边括号,继续入栈:

30cf68770273582807010f02a6b80d09.png

然后又是左边括号,继续入栈:

dc876b2fc097a667b6920c5c4cd1b63f.png

接下来是右边括号,与栈顶元素匹配,“[]”为一对合法的括号,匹配成功栈顶元素出栈:

3ab723fdfc110ea676a35e85a05a9055.png

接下来又是右边括号,与栈顶元素匹配,“()”为一对合法的括号,匹配成功栈顶元素出栈:

cf48520a08dba75feccd3e16a8729854.png

接下来又是右边括号,与栈顶元素匹配,“()”为一对合法的括号,匹配成功栈顶元素出栈:

89c47bff9033d50c3d2c6d3121348583.png

当字符串循环结束并且栈为空栈时,则证明此字符串的括号匹配合法,最终的效果如下图所示:

6f614f212a718e77758e2bc39d44fcdf.png

那么接下来我们就用代码来实现一下整个过程...

实现代码一

public boolean isValid(String s) {
    int slen = s.length(); // 括号的长度
    if (slen % 2 == 1) { // 括号不是成对出现直接返回 false
        return false;
    }
    // 把所有对比的括号存入 map,对比时用
    Map map = new HashMap<>();
    map.put(')', '(');
    map.put('}', '{');
    map.put(']', '[');// 定义栈,用于存取括号(辅助比较)
    Stack stack = new Stack<>();for (int i = 0; i // 循环所有字符char c = s.charAt(i);if (map.containsKey(c)) { // 为右边的括号,如 ')'、'}' 等if (stack.isEmpty() || stack.peek() != map.get(c)) { // 栈为空或括号不匹配return false;
            }
            stack.pop(); // 是一对括号,执行出栈(消除左右括号)
        } else { // 左边括号,直接入栈
            stack.push(c);
        }
    }return stack.isEmpty();
}

我们在 LeetCode 中提交一下代码,执行结果如下:

92c7f7547f46105db36b917b0f6f491e.png

代码解析

以上代码的 map 集合是用于定义括号的匹配规则,比如“)”对应的匹配值是“(”,“]”的匹配值是“[”等,然后我们再去循环待验证的字符串,遇到左括号直接入栈,遇到右括号让它与栈顶元素匹配,等到整个字符串循环结束,如果栈为空则说明字符串的括号合法。

复杂度分析

时间复杂度:O(n),遍历了一遍整个字符串。空间复杂度:O(n)。

实现代码二

除了使用栈之外,我们还可以使用借助 Java 中的 replace 方法来实现,我们可以循环的消除字符串中的括号,比如将“()”或“[]”或“{}”循环得替换为空,最后在执行完成之后如果字符串为空,则说明字符串中的括号是合法的,具体实现代码如下:

public boolean isValid(String s) {
        int len;
        do {
            len = s.length();
            // 消除成双成对的符号
            s = s.replace("()", "").replace("[]", "").
                    replace("{}", "");
        } while (len != s.length()); // 不能再进行替换了,replace 方法没有替换任何字符
        return s.length() == 0;
    }

我们在 LeetCode 中提交一下代码,执行结果如下:

ac76994f841929ebb6e868234d7bb60d.png

从运行结果来看,二者的执行效率相差还是很明显的:

56a470c262b82a2aa619a8ad6281a260.png

总结

本文我们讲了一道 bilibili 的笔试真题,同时它也是栈的经典面试题,我们可以借助栈的特性(先进后出)将所有的左括号入栈,当遇到右括号时让它与栈顶元素进行匹配,当字符串循环结束栈为空时,则说明此字符串的括号是合法的。当然我们在实际面试中,也可以使用 Java 的 replace 方法作为一个保底的实现方案,因为 replace 方法的实现相对更简单一些,只是性能不怎么好。

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

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

相关文章

如何理解字符编码

一直有个困惑&#xff0c;为什么计算机系统搞那么多字符编码&#xff0c;就一个Unicode统一天下不就得了&#xff0c;后来看了篇文章&#xff0c;才多少理解一丁点。 英语的国家&#xff0c;只要一个字节就可以表示全部的字符&#xff0c;一个无符合的字节可以表示256个字符&a…

框架下载_25. Scrapy 框架-下载中间件Middleware

1. Spider 下载中间件(Middleware)Spider 中间件(Middleware) 下载器中间件是介入到 Scrapy 的 spider 处理机制的钩子框架&#xff0c;您可以添加代码来处理发送给 Spiders 的 response 及 spider 产生的 item 和 request2. 激活一个下载DOWNLOADER_MIDDLEWARES要激活一个下载…

android activity 显示无焦点_Android面试题集锦之fragemnt

大家可以关注一下小编&#xff0c;小编以后会一直更新Android相关技术资料文章。创建方式静态创建首先我们需要创建一个xml文件&#xff0c;然后创建与之对应的java文件&#xff0c;通过onCreatView()的返回方法进行关联&#xff0c;最后我们需要在Activity中进行配置相关参数即…

node 安装_VUE项目迁移之node.js的安装

【摘要】由于公司的项目需要迁移到VUE中去, 所以就用到了node.js, 这里简单整理了一下node.js的安装教程和环境变量的配置【作者】田鋆鹏Node.js 安装教程1. 在node.js的官网下载安装包下载地址1: https://nodejs.org/en/下载地址2: http://nodejs.cn/直接下载.msi的安装包即可…

jsp mysql servlet_JSP+Servlet+JDBC+mysql实现的学生成绩管理系统

本系统基于JSPServletMysql一个基于JSPServletJdbc的学生成绩管理系统。涉及技术少&#xff0c;易于理解&#xff0c;适合JavaWeb初学者学习使用。难度等级&#xff1a;入门技术栈编辑器Eclipse Version: 2019-12 (4.14.0)前端技术基础&#xff1a;htmlcssJavaScript框架&#…

mariadb mysql 配置文件_MariaDB/MySQL配置文件my.cnf解读

MariaDB/MySQL的默认设置性能非常差&#xff0c;仅仅起一个功能测试的作用&#xff0c;不能用在生产环境中&#xff0c;因此要对一些参数进行调整优化。当然&#xff0c;对配置文件各参数的调整需要根据实际环境&#xff0c;不同时期不同数量级的数据进行性能优化。MySQL/Maria…

react 事件处理_在React中处理事件

react 事件处理在使用React渲染RESTful服务后&#xff0c;我们创建了简单的UI&#xff0c;用于渲染从RESTful服务获取的员工列表。 作为本文的一部分&#xff0c;我们将扩展同一应用程序以支持添加和删除员工操作。 我们将通过添加/删除员工操作来更新react-app后端api&#x…

多元回归求解 机器学习_金融领域里的机器学习算法介绍:人工神经网络

人工智能的发展在很大程度上是由神经网络、深度学习和强化学习推动的。这些复杂的算法可以解决高度复杂的机器学习任务&#xff0c;如图像分类、人脸识别、语音识别和自然语言处理等。这些复杂任务一般是非线性的&#xff0c;同时包含着大量的特征输入。我们下面我们将分几天的…

apache ignite_使用Spring Data的Apache Ignite

apache igniteSpring Data提供了一种统一而简便的方法来访问不同类型的持久性存储&#xff0c;关系数据库系统和NoSQL数据存储。 它位于JPA之上&#xff0c;添加了另一层抽象并定义了基于标准的设计以在Spring上下文中支持持久层。 Apache Ignite IgniteRepository实现了Spri…

java事件处理过程分布写_Java 9中的进程处理

java事件处理过程分布写一直以来&#xff0c;用Java管理操作系统进程都是一项艰巨的任务。 这样做的原因是可用的工具和API较差。 老实说&#xff0c;这并非没有道理&#xff1a;Java并非旨在达到目的。 如果要管理OS进程&#xff0c;则可以使用所需的Shell&#xff0c;Perl脚本…

mac mysql5.7.9 dmg_Mac 安装 mysql5.7

mac 安装msql 5.7最近使用Mac系统&#xff0c;准备搭建一套本地web服务器环境。因为Mac系统没有自带mysql&#xff0c;所以要手动去安装mysql&#xff0c;本次安装mysql最新版5.7.28。安装步骤参考以下博客https://www.jianshu.com/p/71f81a0c62b2安装成功后&#xff0c;因为密…

安卓系统dicom阅读器_用户分享:电子书阅读器Note Pro,一座贴心的移动图书馆...

本文转载自“什么值得买”官网用户“小良读书”&#xff0c;经作者授权转载。Note Pro&#xff0c;一座贴心的移动图书馆移动图书馆貌美的小书郎10.3寸高清大屏更适合专业书籍的阅读如果说多年前入手了一台kindle paperwite3电纸书阅读器&#xff0c;它让我畅游了书籍的江河&am…

vim 编辑器命令整理

文章目录一、基本使用流程二、普通命令模式&#xff08;一&#xff09;切换到插入模式&#xff08;编辑/写入/输入&#xff09;&#xff08;二&#xff09;切换到可视模式&#xff08;选择文本模式&#xff09;&#xff08;三&#xff09;切换至底行命令模式&#xff08;四&…

activiti dmn_端到端BPM(带有DMN标记)

activiti dmn下周的红帽峰会即将成为有史以来最好的峰会之一&#xff01; 而且&#xff0c;如果您是Drools或jBPM的狂热者&#xff0c;您会很忙 &#xff1a;Signavio和Red Hat之间的合作伙伴关系是我们为您准备的另一个顶级演讲。 邓肯道尔&#xff08;Duncan Doyle&#xff…

netbeans 9_NetBeans 9抢先体验

netbeans 9Java 9即将来临&#xff0c;NetBeans 9也即将来临。在本文中&#xff0c;我们将看到NetBeans 9 Early Access为开发人员提供的支持&#xff0c;以帮助他们构建Java 9兼容的应用程序。 Java 9提供了许多&#xff08;大约90种&#xff09; 新功能&#xff0c;包括模块…

同一个ip能否两次加入组播_组播IGMPv1/v2/v3精华知识汇总

闲言少叙&#xff0c;直奔主题&#xff0c;开说之前先做点铺垫&#xff0c;回顾一下网络的基础知识。D类地址划分回顾组播是IPv4地址分类中的D类&#xff0c;我们回顾一下IPv4的地址划分A类&#xff1a;首bit0&#xff0c;0-127网段&#xff0c;网络掩码8&#xff0c;其中0.0.0…

弹窗要打开或保存来自_如何让 PopClip 支持印象笔记客户端:保存到印象笔记amp;高亮文字...

自从印象笔记品牌独立并发布新APP后&#xff0c;Mac系统下很多工具不再支持与印象笔记客户端进行联动&#xff0c;PopClip 就是其中之一。目前 Popclip 官方并未将印象笔记加入到插件的支持中&#xff0c;不过我们可以手动修改来解决这个问题。Popclip 之所以不支持新版本的印象…

vue 混入对象_特性和混入不是面向对象的

vue 混入对象让我立刻说&#xff0c;我们将在这里讨论的功能是那些迫切需要进行放线手术的人带给面向对象编程的纯粹的毒药 &#xff0c;就像David West在他的《 Object Thinking》一书中所建议的那样。 这些功能具有不同的名称&#xff0c;但是最常见的是traits和mixins 。 我…

glup node 内存不够_Redis:内存被我用完了!该怎么办?

介绍Redis是一个内存数据库&#xff0c;当Redis使用的内存超过物理内存的限制后&#xff0c;内存数据会和磁盘产生频繁的交换&#xff0c;交换会导致Redis性能急剧下降。所以在生产环境中我们通过配置参数maxmemoey来限制使用的内存大小。当实际使用的内存超过maxmemoey后&…

pytest框架_Python最火的第三方开源测试框架——pytest

一、介绍本篇文章是介绍的是Python 世界中最火的第三方单元测试框架&#xff1a;pytest。它有如下主要特性&#xff1a;assert 断言失败时输出详细信息(再也不用去记忆 self.assert* 名称了)自动发现测试模块和函数模块化夹具用以管理各类测试资源对 unittest 完全兼容&#xf…