登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
LeetCode 301 删除无效的括号:python3 题解
LeetCode 301 删除无效的括号:python3 题解
[ 复制链接 ]
拼潦
昨天 00:20
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
题目链接:301. 删除无效的括号
目录
1. 题目含义与核心目标
2. 解题思路分析
思路一:广度优先搜索 (BFS) —— 最直观
思路二:深度优先搜索 (DFS) + 回溯 —— 更高效
3. 代码实现
4. 复杂度分析
5. 总结与建议
1. 题目含义与核心目标
题目描述:
给定一个字符串 s,其中包含小写字母和括号 ( 和 )。我们需要删除
最小数量
的括号,使得剩下的字符串中括号是
有效
的。返回所有可能的结果。
什么是“有效括号”?
左括号 ( 必须有对应的右括号 ) 闭合。
闭合顺序必须正确,不能出现 )( 这种情况。
字母不影响括号的有效性,可以保留。
核心难点:
最小数量
:我们不能随便删,必须保证删得最少。这意味着如果删 1 个括号能变有效,就不能删 2 个。
所有可能
:可能有多种删除方案都能达到“最小删除数”且结果有效,需要全部找出。
去重
:不同的删除位置可能产生相同的字符串(例如 ((),删除第 1 个或第 2 个 ( 结果都是 ()),结果列表中不能有重复。
2. 解题思路分析
这道题主要有两种经典的解法:
广度优先搜索 (BFS)
和
深度优先搜索 (DFS/回溯)
。
思路一:广度优先搜索 (BFS) —— 最直观
逻辑:
想象我们处于第 0 层(原字符串)。
检查当前层的字符串是否有效。如果有效,因为它们是目前删除最少的(层数最低),直接收集所有有效结果并返回。
如果当前层没有有效字符串,我们就生成下一层。下一层的所有字符串,都是由当前层字符串
各删除一个字符
得到的。
重复上述过程,直到找到有效字符串为止。
优点:
天然保证“删除数量最小”。因为 BFS 是按层遍历的,第一层是删 0 个,第二层是删 1 个……第一次遇到有效解的层数,必然是删除最少的。
缺点:
可能会生成大量重复字符串,需要使用 visited 集合去重。
空间消耗较大,因为需要存储每一层的所有状态。
思路二:深度优先搜索 (DFS) + 回溯 —— 更高效
逻辑:
预计算
:先扫描一遍字符串,计算出最少需要删除多少个左括号 (left_remove) 和多少个右括号 (right_remove) 才能可能变有效。
例如:) (,需要删 1 个 ) 和 1 个 (。
回溯删除
:使用递归,尝试删除指定数量的括号。
剪枝与去重
:
如果剩余需要删除的数量小于 0,剪枝。
如果当前括号匹配状态不合法(右括号多于左括号),剪枝。
关键去重
:如果连续出现相同的括号(如 ))),删除第一个和删除第二个结果是一样的。我们规定只删除连续相同括号中的第一个,跳过后续的,避免重复计算。
优点:
效率通常比 BFS 高,因为我们有明确的删除目标数量,不需要盲目尝试。
空间消耗相对较小。
3. 代码实现
下面提供 BFS 解法的完整代码。为了代码的自包含性,我添加了必要的导入和详细的注释。
from typing import List
from collections import deque
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
"""
BFS 解法:
层层递进,第一层是原字符串,第二层是删 1 个字符的所有可能,第三层是删 2 个...
一旦在某一层发现有效字符串,该层所有有效字符串即为答案(保证删除最少)。
"""
# 辅助函数:判断字符串括号是否有效
def isValid(string: str) -> bool:
count = 0
for char in string:
if char == '(':
count += 1
elif char == ')':
count -= 1
# 如果右括号多于左括号,直接无效
if count < 0:
return False
# 最后左括号必须全部闭合
return count == 0
# 队列用于 BFS,初始放入原字符串
queue = deque([s])
# 集合用于记录访问过的字符串,防止重复处理(关键优化)
visited = set([s])
# 存储最终结果
result = []
# 标记是否已经找到了有效解。一旦找到,当前层处理完后就停止,不再深入下一层
found = False
while queue:
# 当前层的节点数量
level_size = len(queue)
# 遍历当前层的所有字符串
for _ in range(level_size):
curr_s = queue.popleft()
# 1. 检查当前字符串是否有效
if isValid(curr_s):
result.append(curr_s)
found = True
# 2. 如果本层已经找到了有效解,我们就不再生成下一层(删除更多字符)了
# 因为题目要求删除最小数量,本层就是最小数量
if found:
continue
# 3. 如果还没找到有效解,生成下一层状态(尝试删除每一个字符)
for i in range(len(curr_s)):
# 跳过非括号字符,因为题目只让删括号(其实删字母也能变有效,但删括号更优,且题目隐含意图是修括号)
# 严格来说,删字母不会改善括号匹配,所以只尝试删括号可以优化,但全删也能过
# 这里为了逻辑通用,尝试删除任意位置字符
if curr_s[i] not in ('(', ')'):
continue
# 生成新字符串:删除索引 i 处的字符
next_s = curr_s[:i] + curr_s[i+1:]
# 如果这个新字符串没被访问过,加入队列
if next_s not in visited:
visited.add(next_s)
queue.append(next_s)
# 如果本层找到了有效解,直接返回,不再处理下一层
if found:
return result
# 如果一直没找到(理论上不会,因为全删完是空串,空串有效),返回空列表或 [""]
return result if result else [""]
复制代码
4. 复杂度分析
假设字符串长度为 \(N\)。
BFS 解法:
时间复杂度
: \(O(2^N)\)。最坏情况下,每个字符都有删或不删两种选择。虽然有 visited 去重,但状态空间依然很大。
空间复杂度
: \(O(2^N)\)。队列和 visited 集合可能存储大量中间字符串。
DFS 解法:
时间复杂度
: \(O(2^N)\)。理论上也是指数级,但因为我们要删除的括号数量通常远小于 \(N\),且有剪枝(open_cnt < 0 时停止)和去重(连续括号只删第一个),实际运行速度远快于 BFS。
空间复杂度
: \(O(N)\)。主要是递归栈的深度和存储结果的空间。
5. 总结与建议
理解题意
:核心是“最小删除”和“所有结果”。
选择方法
:
如果是面试,
DFS 解法
更受青睐,因为它展示了你对剪枝、回溯和去重的掌握,且效率更高。
如果是为了快速理解“最小步数”,
BFS 解法
的逻辑更直观(层序遍历即步数)。
关键点
:
去重
:处理连续相同括号(如 (()时,避免重复计算。
剪枝
:在构建字符串过程中,一旦发现右括号多于左括号,立即停止该分支。
预计算
:先算出要删几个,比盲目尝试要快得多。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
LeetCode
删除
无效
括号
python3
相关帖子
删除 Excel 表格中的重复行 【4 种实用方法】
LeetCode 124 二叉树中的最大路径和:python3 题解
LeetCode 236 二叉树的最近公共祖先:python3 题解
LeetCode 65 有效数字:python3 题解
Excel 删除空白行的 5 种方法 【手动与 Python 自动化】
LeetCode 902 最大为 N 的数字组合:python3 题解
归并排序力扣题(leetcode)
使用 C# 删除 PDF 中的数字签名
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
删除 Excel 表格中的重复行 【4 种实用方法】
2
1005
僚娥
2026-03-05
安全
LeetCode 124 二叉树中的最大路径和:python3 题解
1
508
事值
2026-03-10
业界
LeetCode 236 二叉树的最近公共祖先:python3 题解
0
270
丁若云
2026-03-10
安全
LeetCode 65 有效数字:python3 题解
0
19
忿惺噱
2026-03-10
安全
Excel 删除空白行的 5 种方法 【手动与 Python 自动化】
0
135
济曝喊
2026-03-11
安全
LeetCode 902 最大为 N 的数字组合:python3 题解
0
451
挚魉
2026-03-24
业界
归并排序力扣题(leetcode)
0
844
矛赓宁
2026-03-25
业界
使用 C# 删除 PDF 中的数字签名
0
817
祖娅曦
2026-03-26
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
安全
代码
科技
程序
签约作者
程序园优秀签约作者
发帖
拼潦
昨天 00:20
关注
0
粉丝关注
25
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991125
anyue1937
9994892
kk14977
6845359
4
xiangqian
638210
5
神泱
9522
6
韶又彤
9916
7
宋子
9878
8
荪俗
9018
9
闰咄阅
9995
10
蓬森莉
9870
查看更多
今日好文热榜
195
Electron41+Vite8.0+DeepSeek桌面端AI助手|
674
OPUS编解码器在audio DSP上的移植和应用
469
SpringCloud进阶--Seata与分布式事务
987
大模型私有化部署指南:从“一键安装”到“
624
大模型私有化部署指南:从“一键安装”到“
885
SpringCloud进阶--Seata与分布式事务
171
SpringCloud进阶--Seata与分布式事务
785
Oracle SQL经典练习50题 | 附答案
205
gitru:一个由 Rust 打造的零依赖 Git 提交
929
gitru:一个由 Rust 打造的零依赖 Git 提交
266
gitru:一个由 Rust 打造的零依赖 Git 提交
855
gitru:一个由 Rust 打造的零依赖 Git 提交
426
gitru:一个由 Rust 打造的零依赖 Git 提交
694
ESP32S3 USB MSC 调试全过程记录
639
瑞芯微工业级芯加持,正点原子RK3562J开发
56
gitru:一个由 Rust 打造的零依赖 Git 提交
784
营销自动化数据驱动 - 多源数据 OLAP 架构
534
C# .NET 周刊|2026年3月1期
151
【GUI-Agent】阶跃星辰 GUI-MCP 解读---(5)
869
LangChain教程-3、Langchian进阶