探索有效括号 力扣第20题:从栈到递归的多角度解法 【含图解 python】

题目描述

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’ 和 ‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例输入:

 s = "()"
输出: true
输入: s = "()[]{}"
输出: true
输入: s = "(]"
输出: false

解题思路

下表对比了使用栈、优化的栈方法和递归方法解决有效的括号问题的时间复杂度、空间复杂度以及各自的优缺点:
不同方法对比

方法一:栈

栈算法思路:

最直接的方法是使用一个栈。每当我们遇到一个开括号时,我们将其推入栈中。对于每一个闭括号,我们检查栈顶的元素。如果栈顶的开括号与当前的闭括号匹配,我们将其从栈中弹出,否则说明括号无法有效闭合,返回 false。遍历完整个字符串后,如果栈为空,则说明所有括号都有效闭合,返回 true。

代码示例:
def isValid(s: str) -> bool:stack = []mapping = {")": "(", "}": "{", "]": "["}for char in s:if char in mapping:top_element = stack.pop() if stack else '#'if mapping[char] != top_element:return Falseelse:stack.append(char)return not stack
算法图解

通过使用表格来呈现栈操作的过程可以使理解更加直观。以字符串 s = “([{}])” 为例,我们来详细说明栈操作的过程:
步骤
入栈出栈步骤

通过上表可以看出,每一次遇到闭括号时,栈顶的元素正好是与之匹配的开括号,因此该字符串是有效的括号字符串。遍历结束后,栈为空,这意味着所有的括号都被有效匹配。

在上表中,“栈的状态”列表示了在每一步操作之后栈中的元素,“操作”列说明了是将字符入栈还是因为匹配成功而将栈顶元素弹出。

这种使用栈来匹配括号的方法,不仅适用于包含三种括号的情况,同样适用于只包含一种或两种括号的字符串。其关键在于利用栈这一数据结构的特性,即后进先出,来确保括号的顺序和类型都正确匹配。这个过程是解决此类问题的一个典型算法思想。

复杂度分析:

时间复杂度:O(n),其中 n 是字符串的长度。我们只遍历了一遍字符串。
空间复杂度:O(n),在最坏的情况下(全部都是开括号),我们将全部字符都放入栈中。

方法二:优化的栈方法

在方法一的基础上,我们可以对栈的使用进行一些优化,以进一步提高算法的效率和简洁性。优化的核心思想是直接在遍历字符串时检查是否为闭括号,如果是,则判断栈顶元素是否为对应的开括号,如果不是或栈为空,则直接返回 false;否则,将栈顶元素弹出。如果遍历完毕后栈为空,则说明所有括号都被正确匹配,返回 true。

优化点:
•	直接映射闭括号到开括号: 通过建立一个从闭括号到开括号的映射,这样可以在遍历字符串时快速检查和弹出栈顶元素。
•	提前返回: 在确定字符串不是有效的括号序列的情况下提前返回,避免不必要的遍历。
代码示例:
def isValid(s: str) -> bool:stack = []# 闭括号到开括号的映射mapping = {")": "(", "}": "{", "]": "["}for char in s:if char in mapping:  # 如果是闭括号top_element = stack.pop() if stack else '#'if mapping[char] != top_element:return False  # 不匹配则提前返回else:stack.append(char)  # 开括号入栈return not stack  # 栈空说明匹配
算法分析:

时间复杂度: O(n),其中 n 是字符串的长度。我们只遍历了一遍字符串。
空间复杂度: O(n),在最坏的情况下(全部都是开括号),我们将全部字符都放入栈中。

方法三:递归解决有效的括号问题

递归方法在解决有效的括号问题时采用的是一种自顶向下的分解策略,通过不断移除字符串中直接相邻的匹配括号对,直到无法继续移除为止。如果最终得到的是一个空字符串,则原始字符串是有效的括号字符串;否则,不是有效的括号字符串。
递归思路基本情况:如果字符串为空,返回 true,表示是有效的括号字符串。
递归步骤:找到第一个匹配的括号对,移除它们,然后对剩下的字符串进行递归判断。

代码示例
def isValid(s: str) -> bool:# 函数用于移除字符串中的一对括号def removePair(s):pairs = ["()", "{}", "[]"]for pair in pairs:if pair in s:return s.replace(pair, "", 1)  # 只替换一次return s# 递归移除所有括号对while len(s) > 0:new_s = removePair(s)if new_s == s:  # 如果字符串未改变,说明没有括号可以移除return Falses = new_sreturn True
算法分析

时间复杂度:最坏情况下为 O(n^2),其中 n 是字符串的长度。每次移除一对括号需要 O(n) 的时间,并且每次移除都要遍历整个字符串。
空间复杂度:由于是递归调用,空间复杂度取决于递归调用的深度,最坏情况下为 O(n)。

优缺点

优点:递归方法直观易懂,能够清晰地表达移除匹配括号对的逻辑。
缺点:效率较低,尤其是在处理较长的字符串时,由于每次递归都需要遍历整个字符串,导致较大的时间和空间开销。

应用场景

有效的括号问题在编程语言的编译器设计、表达式求值等方面都有广泛的应用。例如,编译器在解析代码时需要检查括号是否匹配,以保证代码的结构正确。

结论

有效的括号是一个典型的使用栈解决的问题,通过遍历字符串并利用栈的先进后出的特性来匹配每一种类型的括号。此算法简洁且效率高,适合解决类似的括号匹配问题。

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

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

相关文章

YOLOv8打印模型结构配置信息并查看网络模型详细参数:参数量、计算量(GFLOPS)

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

代码混淆和加固,保障应用程序的安全性

摘要:本文将详细介绍iOS技术博主在保护应用程序代码安全方面的两种重要方式:代码混淆和代码加固。通过代码混淆和加固,博主可以有效防止他人对应用程序进行逆向工程和篡改,提高应用程序的安全性。 引言:作为iOS技术博主…

SpringCloud 微服务

什么是微服务: 微服务方案: 1. SpringCloud NetFlix 2. Dubbo 3. SpringCloud Alibaba 解决了什么问题: 1. 服务过多,客户端怎么访问 2. 服务过多,服务间怎么传值 3. 服务过多,如何治理 4. 服务过多…

WordPress网站备份和迁移教程

我们之前遇到购买了hostease的客户需要进行wordpress的网站备份的迁移操作。 以下是一份完整的指南,介绍了备份和迁移WordPress网站的步骤: 步骤一:备份WordPress网站 使用插件进行备份: 安装并激活备份插件,例如Up…

Redis数据库:高可用(主从复制、哨兵模式、cluster集群)

目录 前言 一、Redis数据库高可用 二、Redis 主从复制 1、Redis主从复制概述 1.1 Redis主从复制概念 1.2 Redis主从复制的作用 1.3 Redis主从复制的流程 2、搭建Redis主从复制 2.1 环境部署 2.2 主服务器修改配置文件 2.3 从服务器修改配置文件 2.4 测试主从复制效…

基于Java+SpringBoot+vue3+uniapp口红销售/商城管理系统设计与实现

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

360加固脱壳实战

下载[]打开app使用frida -U -f com.xxx.xxx.xxx -l dupDex.js --no-pause<br> 命令 或者使用frida-hexdump -U -f com.inmo.inmolife命令在com.xxx.xxx.xxx 中寻找dex文件 或者在输出的日志中有输出路径使用dex2jar工具把dex文件转为jar文件 d2j-dex2jar.sh *.dex -d --…

纯小白蓝桥杯备赛笔记--DAY10(字符串)

文章目录 KMP字符串哈希算法简介&#xff1a;斤斤计较的小z--2047字符串hash Manacher回文串的性质算法简介最长回文子串 字典树基础朴素字符串查找步骤前缀判定--1204 01tire算法简介&#xff1a;例题1&#xff1a;例题2&#xff1a; KMP字符串哈希 算法简介&#xff1a; 真前…

ppt秒换封面的办法

ppt中封面对PPT的B格有一定的提升 如何快速制作一个封面呢 办法1&#xff1a;快速制作封面更换背景图片的办法 步骤1&#xff1a;ppt背景图片用纯色填充&#xff0c;文字内容格局布置好 2.在网上找好你需要的背景图片&#xff0c;复制图片 3.在ppt背景上&#xff0c;右键--“…

淘宝销量API商品详情页原数据APP接口测试㊣

淘宝/天猫获得淘宝app商品详情原数据 API 返回值说明 item_get_app-获得淘宝app商品详情原数据 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地…

测开面经(Git经典题目,Git入门)

1. GitHub是什么 a. Git是一个分布式版本控制系统&#xff0c;作用是跟踪、管理和协调软件开发项目中的代码更改。 b. 提供了一种有效的方式来管理代码的版本历史&#xff0c;以及多人协作开发的能力。 2. Git的作用有哪些 a. 版本控制&#xff1a;Git可以记录每次代码更改的…

(学习日记)2024.04.11:UCOSIII第三十九节:软件定时器

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…