回溯算法学习笔记(二)组合型:组合,组合总和III,括号生成

【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】

参考:1. 回溯算法套路②组合型回溯+剪枝【基础算法精讲 15】_哔哩哔哩_bilibili 2. https://www.youtube.com/watch?v=kyLxTdsT8ws&list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O&index=65

ps:笔记和代码按本人理解整理,重思路

上期笔记

回溯算法学习笔记(一)子集型:电话号码的字母组合,子集,分割回文串-CSDN博客

题目1:组合

77. 组合 - 力扣(LeetCode)

  • 题意:返回范围 [1, n] 中所有可能的 k 个数的组合
  • 组合回溯过程(以 n = 4, k = 2举例)
  • 代码:
    class Solution:
        def combine(self, n: int, k: int) -> List[List[int]]:
            results = []
            path = []
            def backtracking(start, k): # k表示还要加多少数
                if k == 0: # k为0说明组合已完成
                    results.append(path[:]) 
                    return 
                for i in range(start, n+1):
                    path.append(i)
                    backtracking(i+1, k-1) # 新的start为i+1,加入一个数后k要-1
                    path.pop() # 回溯(恢复现场)
            backtracking(1, k)
            return results
    

题目2:组合总和III

216. 组合总和 III - 力扣(LeetCode)

  • 题意:找出所有相加之和为 n 的 k 个数的组合,只使用数字1到9,每个数字最多用一次
  • 对比上题的变化:需要计算和,并且要满足和为k的条件才能把组合加进结果
  • 代码:
    from typing import List
    
    class Solution:
        def combinationSum3(self, k: int, n: int) -> List[List[int]]:
            results = []
            path = []  # 记录组合
            sum_ = 0  # 记录组合的和
            def backtrack(start, k):
                nonlocal sum_
                if k == 0 and sum_ == n:  # 组合已满且满足和为0
                    results.append(path[:])  
                    return 
                elif k == 0: # 组合已满但不满足和为0
                    return 
                
                for i in range(start, 10):  # 数字范围是1到9
                    if i > n:  # 已经不能满足和为n(剪枝)
                        break
                    path.append(i)
                    sum_ += i
                    backtrack(i+1, k-1)
                    path.pop()  # 回溯
                    sum_ -= i
    
            backtrack(1, k)
            return results

题目3:括号生成

22. 括号生成 - 力扣(LeetCode)

  • 变化:加到组合的只有左括号或者右括号
  • 记录还可以加多少左括号和右括号
  • 条件:
    • 如果要加左括号:左括号未加满
    • 如果要加右括号:当前组合里,左括号多于右括号
  • 代码:
    class Solution:
        def generateParenthesis(self, n: int) -> List[str]:
            left_brackets = 0
            results = []
            path = ''
            def backtracking(left_brackets, right_brackets):
                nonlocal path
                if left_brackets == 0 and right_brackets == 0:
                    results.append(path[:])
                    return 
                
                if left_brackets > 0:  # 可加左括号
                    path += '('
                    backtracking(left_brackets-1, right_brackets)
                    path = path[:-1]
                
                if right_brackets > left_brackets: # 可加右括号
                    path += ')'
                    backtracking(left_brackets, right_brackets-1)
                    path = path[:-1]
    
            backtracking(n, n)
            return results
                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值