leetcode:301. 删除无效的括号【括号套路+bfs优化】

本文介绍两种去除无效括号的方法:状态压缩与BFS。状态压缩适用于较小字符串,通过位操作跳过无效组合;BFS则从原始字符串逐步删除括号,直至找到所有合法组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

分析

简单的括号check函数
然后一开始想的是状态压缩判断
但是这样会遍历到很多无效情况
因此,我们可以考虑从原始s一个个括号删除(因为是最小删除)
这样一旦遇到满足的删除个数立即返回即可,不需要额外多余的遍历

无脑状态压缩

class Solution:
    def removeInvalidParentheses(self, s: str) -> List[str]:
        # 状态压缩
        maxLength = 0
        ans = set()
        n = len(s)

        # 字母的位置不能删
        alpha = []
        for i in range(n):
            if s[i] in ascii_lowercase:
                alpha.append(i)
        #print(alpha)

        # 检查是否有效
        def check(s):
            # 辅助栈
            st = []
            for c in s:
                if c in ascii_lowercase:
                    continue
                if st and st[-1] == '(' and c == ')':
                    st.pop()
                else:
                    st.append(c)
            #print(st)
            return len(st) == 0


        # 状态压缩(但是对字母是不必要的)
        for i in range(1 << n):
            si = bin(i)[2:].zfill(n)
            # 保证不删掉字母
            flag = True
            for j in alpha:
                if si[j] == '0':
                    flag = False
                    break
            if not flag:
                continue
            
            now = ''
            for j, v in enumerate(si):
                if v == '1':
                    now += s[j]
            
            if len(now) < maxLength:
                continue
            
            if check(now) and len(now) == maxLength:
                ans.add(now)           
            elif check(now) and len(now) > maxLength:
                maxLength = len(now)
                ans = set()
                ans.add(now)
        
        return list(ans)

bfs解决最小删除问题(从原str开始删括号)

class Solution:
    def removeInvalidParentheses(self, s: str) -> List[str]:

        # 检查是否有效
        def check(s):
            # 辅助栈
            st = []
            for c in s:
                if c in ascii_lowercase:
                    continue
                if st and st[-1] == '(' and c == ')':
                    st.pop()
                else:
                    st.append(c)
            #print(st)
            return len(st) == 0

        ans = []

        # 使用bfs逐个括号删除(忽略字母干扰)
        curSet = set([s])
        while curSet:
            # 如果当前set中有合法的就放进去ans
            ans = [s for s in curSet if check(s)]
            if ans:  
                return ans
            nextSet = set()
            # 针对当前set的每一个砍掉一个括号
            for s in curSet:
                for i, c in enumerate(s):
                    if c == '(' or c == ')':
                        nextSet.add(s[:i] + s[i + 1:])
            curSet = nextSet

总结

最小删除问题由于是原s的子串
因此可以根据上一个删除的一位位删除
这样每一层的bfs都是保证元素个数相同的所有情况
然后一旦有合法的就立即返回
同时不会被无效的字母干扰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白速龙王的回眸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值