刷题记录:删除无效的括号

删除无效的括号
考虑到题目要求求出所有最长组合,考虑用暴力搜索尝试每一种情况,并在特定情况进行剪枝。

import copy
class Solution:
    def removeInvalidParentheses(self, s):
    # 统计给定的字符串中 左括号 和 右括号 的数目 以便在回溯时进行剪枝
    # 统计应该删除的 左括号 和 右括号 数目 来计算方法如下:
    # 1)当右括号全部计数完成后,剩余的左括号应该全部删除
    # 2)当一个右括号出现时 左边没有相应的左括号匹配,应该删除
        l_count, l_remove = 0, 0
        r_count, r_remove = 0, 0
        for i in s:
            if i == '(':
                l_count += 1
                l_remove += 1
            elif i == ')':
                r_count += 1
                if l_remove > 0:
                    l_remove -= 1
                else:
                    r_remove += 1
        n = len(s)
        n_comb = n - r_remove - l_remove
        # 根据 应该删除的 左右括号的数目 计算出最后答案字符串的长度
        max_score = min(l_count, r_count)
        # 回溯过程中的最高得分 记遍历到左括号时 +1分, 右括号 -1分
        ans = []

        def backtracking(idx, cur_comb, l_remove, r_remove, score):
        	# idx: s中的下标 ;cur_comb:当前扫描字符串长度
            # base case
            nonlocal max_score
            if l_remove < 0 or r_remove < 0 or score < 0 or score > max_score:
                return
            if len(cur_comb) == n_comb and score == 0:# 同时满足两个条件时 加入答案
                ans.append(copy.deepcopy(cur_comb))
            if idx == n:# 下标越界 直接返回
                return
            parenthese = s[idx]
            if parenthese == '(':
                backtracking(idx + 1, cur_comb, l_remove - 1, r_remove, score)
                # 删除当前括号
                backtracking(idx + 1, cur_comb + parenthese, l_remove, r_remove, score + 1)
                # 保留当前括号
            elif parenthese == ')':
                backtracking(idx + 1, cur_comb, l_remove, r_remove - 1, score)
                # 删除当前括号
                backtracking(idx + 1, cur_comb + parenthese, l_remove, r_remove, score - 1)
                # 保留当前括号
            else:
                backtracking(idx + 1, cur_comb + parenthese, l_remove, r_remove, score)
                # 其他字符 保留
        backtracking(0, "", l_remove, r_remove, 0)
        # 从第一个字符DFS
        ans =  list(set(ans))
        # 集合去重
        return ans
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值