LeetCode编程练习,21天每日一题记录

本文介绍如何通过回溯算法解决LeetCode题目301删除无效括号,讲解了回溯思想的应用和剪枝优化,助你提高编程能力。通过实例展示并实现一个解决方案,包括lremove和rremove的计算以及字符串有效性检查。
摘要由CSDN通过智能技术生成

学习目标:

通过LeetCode编程练习,坚持21天每日一题,提高编程水平。


学习内容:

301. 删除无效的括号

题目内容:

给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

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

运用思想:

①回溯算法思想

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

个人理解跟深度优先搜索算法类似,在本题中,可先利用括号匹配的规则求出字符串s中最少需要去掉的左括号数lremove和右括号数rremove,然后逐步去掉lremove个左括号和rremove个右括号,同时检测字符串是否符合规则,如何符合规则则输出为可能的结果。我们利用回溯算法来尝试搜索所有可能的结果。

②剪枝操作

回溯算法通常伴随着剪枝操作,这道题的剪枝操作通过去掉一些不符合题意和规则的搜索操作,提高算法的效率。代码中有详细步骤。


学习产出:

class Solution:
    def removeInvalidParentheses(self, s: str) -> List[str]:
        res = []
        # lremove,rremove记录剩下要删除的左右括号个数。
        lremove, rremove = 0, 0 
        for c in s:
            if c == '(':
                lremove += 1
            elif c == ')':
                if lremove == 0:
                    rremove += 1
                else:
                    lremove -= 1
        
        #下面这个函数能判断字符串中的括号是否正确匹配,即左右括号按顺序排列,且数目相同。
        def isValid(str):
            cnt = 0
            for c in str:
                if c == '(':
                    cnt += 1
                elif c == ')':
                    cnt -= 1
                    if cnt < 0:
                        return False
            return True   #true
        
        def remove(s, start, lcount, rcount, lremove, rremove):
            # remove操作递归退出条件:剩下要删除的括号数为0且字符串符合正确性。
            if lremove == 0 and rremove == 0:
                if isValid(s):
                    res.append(s)
                return
            
            for i in range(start, len(s)):
                #去重操作,
                if i > start and s[i] == s[i - 1]:
                    if s[i] == '(':
                        lcount += 1
                    elif s[i] == ')':
                        rcount += 1
                    continue

                #回溯条件①:剩余的字符数目小于要删除的括号个数,直接返回。
                if lremove + rremove > len(s) - i:
                    break
                #去掉左括号操作
                if lremove > 0 and s[i] == '(':
                    remove(s[:i] + s[i+1:], i, lcount, rcount, lremove - 1, rremove);
                #去掉右括号操作
                if rremove > 0 and s[i] == ')':
                    remove(s[:i] + s[i+1:], i, lcount, rcount, lremove, rremove - 1);
                #记录字符串中已有的括号数量
                if s[i] == '(':
                    lcount += 1
                elif s[i] == ')':
                    rcount += 1
                #回溯条件②:当前右括号数量大于左括号数量,表示非法,直接返回。
                if rcount > lcount:
                    break
        
        remove(s, 0, 0, 0, lremove, rremove)
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值