当前位置: 首页 > news >正文

回溯题目:删除无效的括号

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:删除无效的括号

出处:301. 删除无效的括号

难度

8 级

题目描述

要求

给定一个由括号和字母组成的字符串s \texttt{s}s,删除最小数量的无效括号,使得输入的字符串有效。

返回所有可能的结果。可以按任意顺序返回答案。

示例

示例 1:

输入:s = "()())()" \texttt{s = "()())()"}s = "()())()"
输出:["(())()","()()()"] \texttt{["(())()","()()()"]}["(())()","()()()"]

示例 2:

输入:s = "(a)())()" \texttt{s = "(a)())()"}s = "(a)())()"
输出:["(a())()","(a)()()"] \texttt{["(a())()","(a)()()"]}["(a())()","(a)()()"]

示例 3:

输入:s = ")(" \texttt{s = ")("}s = ")("
输出:[""] \texttt{[""]}[""]

数据范围

  • 1 ≤ s.length ≤ 25 \texttt{1} \le \texttt{s.length} \le \texttt{25}1s.length25
  • s \texttt{s}s由小写英语字母以及括号‘(’ \texttt{`('}‘(’‘)’ \texttt{`)'}‘)’组成
  • s \texttt{s}s中至多含20 \texttt{20}20个括号

解法一

思路和算法

这道题要求从字符串s ss中删除最少数量的无效括号,使得字符串中剩余的字符有效。最少操作符合广度优先搜索的应用场景,因此可以使用广度优先搜索得到删除次数最少的情况下的全部有效字符串。

广度优先搜索的做法是,对于字符串中的每个括号,将其删除之后得到一个新的字符串,将新的字符串在下一轮搜索。

0 00轮遍历初始字符串s ss,第i ii轮遍历所有删除i ii个括号之后的字符串,即每一轮遍历的字符串的长度依次递减。对于当前轮的全部字符串,判断每个字符串是否有效,如果有效则将其添加到答案中。如果一轮结束之后,答案不为空,则找到删除次数最少的情况下的全部有效字符串,此时结束搜索,返回答案。

实现方面有以下两点说明。

  1. 如果当前字符串中有两个相邻的相同括号字符,则删除其中任意一个括号字符得到的新字符串是相同的,因此只需要考虑删除其中一个括号字符得到的新字符串,跳过相邻的其余相同括号字符。

  2. 使用哈希集合存储每一轮遍历的字符串,可以确保同一个字符串只访问一次。

代码

classSolution{publicList<String>removeInvalidParentheses(Strings){List<String>valid=newArrayList<String>();Set<String>set=newHashSet<String>();set.add(s);while(!set.isEmpty()){for(Stringstr:set){if(isValid(str)){valid.add(str);}}if(!valid.isEmpty()){break;}Set<String>nextSet=newHashSet<String>();for(Stringstr:set){intlength=str.length();for(inti=0;i<length;i++){charc=str.charAt(i);if((i>0&&c==str.charAt(i-1))||(c!='('&&c!=')')){continue;}StringnextStr=str.substring(0,i)+str.substring(i+1);nextSet.add(nextStr);}}set=nextSet;}returnvalid;}publicbooleanisValid(Stringstr){intcount=0;intlength=str.length();for(inti=0;i<length;i++){charc=str.charAt(i);if(c=='('){count++;}elseif(c==')'){count--;}if(count<0){returnfalse;}}returncount==0;}}

复杂度分析

  • 时间复杂度:O ( n 2 × 2 n ) O(n^2 \times 2^n)O(n2×2n),其中n nn是字符串s ss的长度。字符串s ss最多有2 n 2^n2n个子序列,因此广度优先搜索的过程中最多遍历2 n 2^n2n个不同的字符串,对于每个字符串的操作时间是O ( n 2 ) O(n^2)O(n2)的时间,将每个有效字符串添加到答案需要O ( n ) O(n)O(n)的时间,因此时间复杂度是O ( n 2 × 2 n ) O(n^2 \times 2^n)O(n2×2n)

  • 空间复杂度:O ( n × 2 n ) O(n \times 2^n)O(n×2n),其中n nn是字符串s ss的长度。字符串s ss最多有2 n 2^n2n个子序列,因此广度优先搜索的过程中最多遍历2 n 2^n2n个不同的字符串,每个字符串的长度不超过n nn,因此空间复杂度是O ( n × 2 n ) O(n \times 2^n)O(n×2n)

解法二

思路和算法

也可以使用回溯的做法得到删除次数最少的情况下的全部有效字符串。

由于回溯本身不保证得到最少操作的答案,因此需要首先遍历字符串得到左括号和右括号的最少删除次数。计算左括号和右括号的最少删除次数时,需要考虑剩余的左括号和右括号的个数相等且任意前缀中的左括号个数大于等于右括号个数。具体做法是,使用leftRemove \textit{leftRemove}leftRemoverightRemove \textit{rightRemove}rightRemove分别表示左括号和右括号的最少删除次数,从左到右遍历字符串s ss,执行如下操作。

  • 如果遇到左括号,则将leftRemove \textit{leftRemove}leftRemove1 11

  • 如果遇到右括号,则当leftRemove = 0 \textit{leftRemove} = 0leftRemove=0时将rightRemove \textit{rightRemove}rightRemove1 11,当leftRemove > 0 \textit{leftRemove} > 0leftRemove>0时将leftRemove \textit{leftRemove}leftRemove1 11

根据有效括号的定义,一定可以从s ss中删除leftRemove \textit{leftRemove}leftRemove个左括号和rightRemove \textit{rightRemove}rightRemove个右括号得到有效的字符串。

得到左括号和右括号的最少删除次数之后,执行回溯,回溯过程中需要维护当前字符串str \textit{str}str、开始下标index \textit{index}index、左括号的剩余删除次数leftRemove \textit{leftRemove}leftRemove和右括号的剩余删除次数rightRemove \textit{rightRemove}rightRemove,回溯的做法如下。

  • 如果leftRemove = rightRemove = 0 \textit{leftRemove} = \textit{rightRemove} = 0leftRemove=rightRemove=0,则所有的删除次数都用完,当str \textit{str}str有效时将str \textit{str}str添加到答案中。

  • 如果leftRemove \textit{leftRemove}leftRemoverightRemove \textit{rightRemove}rightRemove中至少有一个大于0 00,则需要继续删除括号。对于从index \textit{index}index开始的每个下标i ii,如果str [ i ] \textit{str}[i]str[i]是括号且对应的剩余删除次数大于0 00,则得到将str [ i ] \textit{str}[i]str[i]删除后的新字符串,将对应的剩余删除次数减1 11,从开始下标i ii继续回溯。

回溯过程中有以下两处可以剪枝。

  1. 如果当前字符串的剩余字符个数少于leftRemove + rightRemove \textit{leftRemove} + \textit{rightRemove}leftRemove+rightRemove,则即使将剩余字符全部删除也不可能得到有效字符串,因此停止当前回溯。

  2. 如果当前字符串中有两个相邻的相同括号字符,则删除其中任意一个括号字符得到的新字符串是相同的,因此只需要考虑删除其中一个括号字符得到的新字符串,跳过相邻的其余相同括号字符。

代码

classSolution{List<String>valid=newArrayList<String>();publicList<String>removeInvalidParentheses(Strings){intleftRemove=0,rightRemove=0;intlength=s.length();for(inti=0;i<length;i++){charc=s.charAt(i);if(c=='('){leftRemove++;}elseif(c==')'){if(leftRemove==0){rightRemove++;}else{leftRemove--;}}}backtrack(s,0,leftRemove,rightRemove);returnvalid;}publicvoidbacktrack(Stringstr,intindex,intleftRemove,intrightRemove){if(leftRemove==0&&rightRemove==0){if(isValid(str)){valid.add(str);}}else{intlength=str.length();for(inti=index;i<length;i++){if(length-i<leftRemove+rightRemove){break;}charc=str.charAt(i);if(i>index&&c==str.charAt(i-1)){continue;}StringnextStr=str.substring(0,i)+str.substring(i+1);if(c=='('&&leftRemove>0){backtrack(nextStr,i,leftRemove-1,rightRemove);}elseif(c==')'&&rightRemove>0){backtrack(nextStr,i,leftRemove,rightRemove-1);}}}}publicbooleanisValid(Stringstr){intcount=0;intlength=str.length();for(inti=0;i<length;i++){charc=str.charAt(i);if(c=='('){count++;}elseif(c==')'){count--;}if(count<0){returnfalse;}}returncount==0;}}

复杂度分析

  • 时间复杂度:O ( n 2 × 2 n ) O(n^2 \times 2^n)O(n2×2n),其中n nn是字符串s ss的长度。字符串s ss最多有2 n 2^n2n个子序列,因此回溯的过程中最多遍历2 n 2^n2n个不同的字符串,对于每个字符串的操作时间是O ( n 2 ) O(n^2)O(n2)的时间,将每个有效字符串添加到答案需要O ( n ) O(n)O(n)的时间,因此时间复杂度是O ( n 2 × 2 n ) O(n^2 \times 2^n)O(n2×2n)

  • 空间复杂度:O ( n × 2 n ) O(n \times 2^n)O(n×2n),其中n nn是字符串s ss的长度。字符串s ss最多有2 n 2^n2n个子序列,因此回溯的过程中最多遍历2 n 2^n2n个不同的字符串,每个字符串的长度不超过n nn,因此空间复杂度是O ( n × 2 n ) O(n \times 2^n)O(n×2n)

http://www.jsqmd.com/news/1242065/

相关文章:

  • AI搜索学术检索终极对比报告(2024Q2):Scite AI vs Consensus vs Elicit vs 本土知网智搜,响应速度/准确率/引用溯源能力四维压测结果首次公开
  • 【企业级AI选型决策指南】:拒绝黑盒评估!用BLEU+BERTScore+FactScore+人工盲测四维打分法精准识别高风险模型
  • 【Redis】----如何测试redis单机的最大并发
  • 音乐推荐系统
  • Python的GIL把我坑惨了,原来多线程和多进程的区别这么大
  • GradPaper深度体验3个月:优点、缺点、使用技巧全分享
  • Python requests.get()接口自动化测试实战指南
  • AI写外文论文工具哪个好?2026主流工具深度测评与推荐
  • 盈启鲲鹏数字人直播省钱方案
  • 郑州出手二手手表去哪?2026 名表回收报价公开 - 资讯洞察员
  • 半导体/高端制造 设计EDA首席科学家 18维度权威简历范本
  • Windows命令提示行中的常用指令
  • 汽车玻璃原片衬纸定制规格,可裁切最大尺寸
  • 生物医学论文降AI工具免费推荐:2026年生物医学毕业论文降AI4.8元知网达标完整指南
  • Hugging Face遭自主AI Agent入侵,防御方用AI反击
  • AI驱动的Scrum迭代升级手册(从需求评审到自动化验收,7步实现交付周期压缩47%)
  • Python计算机毕设之基于 Python 的健康饮食数据统计分析平台 居民膳食习惯监测与健康预警系统(完整前后端代码+说明文档+LW,调试定制等)
  • 编写程序统计模仿他人方案的次数,设定每周原创方案最低数量标准,强制独立思考。
  • 帝舵广州售后资质核验报告|权威收录正规维修网点信息(2026年7月最新) - 帝舵售后服务中心官网
  • 实验10 Bezier曲线生成-实验提高-控制点生成B样条曲线
  • 结尾号召写不好,再好的AI文案也白费,深度拆解头部品牌私藏的7类高响应结尾结构
  • Mac开发环境配置全攻略:从基础到专业
  • AI论文写作工具:从选题到终稿的智能解决方案
  • AI Town地图编辑器入门:零基础构建自主AI虚拟世界
  • 分布式数据库Redis的简介、安装与设置使用指令
  • 从AI初稿到出版级干货:编辑总监绝不外传的4轮精修法(含可直接套用的Checklist表格)
  • 【私藏级推荐】:2024年唯一值得个人长期投入的3个轻量化AI模型(附量化教程+Mac/Win/Linux三端兼容配置)
  • 汽车密封件和磁材的AI视觉检测方案——缺陷分类与光学成像的工程原理
  • AI课程越来越多,为什么你还是学不会AI?
  • 政务与医疗大模型合规安全:在监管要求下落地 AI 防护