【LeetCode 刷题】回溯算法-组合问题

此博客为《代码随想录》二叉树章节的学习笔记,主要内容为回溯算法组合问题相关的题目解析。

文章目录

77. 组合

题目链接

python 复制代码
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res, path = [], []

        def dfs(start: int, n: int) -> None:
            if len(path) > k or n < 0:
                return
            if len(path) == k and n == 0:
                res.append(path.copy())
                return
            for i in range(start, 10):
                path.append(i)
                dfs(i + 1, n - i)
                path.pop()
        
        dfs(1, n)
        return res
  • dfs 函数的参数为起始位置;由于每个数只能用一次,因此在后序的递归过程中只需调整起始位置为上一个选择的元素的后一个位置即可,也即 dfs(i + 1)
  • 如果 append() 的时候不添加 .copy(),则放入结果列表的仍然是原始 path 变量的引用,对 path 的修改会影响到结果列表
  • 优化点:for 循环选择的起始位置之后的元素个数已经不足需要的元素个数了,则可以直接剪枝

216.组合总和III

题目链接

python 复制代码
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res, path = [], []

        def dfs(start: int, n: int) -> None:
            if len(path) == k and n == 0:
                res.append(path.copy())
                return
            if len(path) > k or n < 0:
                return
            for i in range(start, 10):
                path.append(i)
                dfs(i + 1, n - i)
                path.pop()
        
        dfs(1, n)
        return res
  • dfs 的两个参数分别表示:起始位置,剩余要满足的值
  • 相较于上题,额外添加了总和为 n 的限制

17.电话号码的字母组合

题目链接

python 复制代码
class Solution:
    MAPPING = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
    def letterCombinations(self, digits: str) -> List[str]:
        res, path = [], []
        if not digits: 
            return res

        def dfs(start: int) -> None:
            if start == len(digits):
                res.append(''.join(path))
                return
            for c in self.MAPPING[int(digits[start])]:
                path.append(c)
                dfs(start + 1)
                path.pop()
            
        dfs(0)
        return res
  • dfs 函数的参数为起始位置,也即为在该轮递归中要处理的第 start 位 digits

39. 组合总和

题目链接

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        res, path = [], []

        def dfs(start: int, target: int) -> None:
            if target < 0:
                return
            if target == 0:
                res.append(path.copy())
            for i in range(start, len(candidates)):
                if i > start and candidates[i] == candidates[i-1]:
                    continue
                path.append(candidates[i])
                dfs(i, target - candidates[i])
                path.pop()
        
        dfs(0, target)
        return res
  • dfs 的两个参数分别表示:起始位置,剩余要满足的值;由于此题元素可以重复使用,因此在递归调用时,起始位置不变,即 dfs(i, ...)
  • 此题要求结果列表中的组合不重复,通过 candidates[i] != candidates[i-1] 来保证,因为如果 candidates[i] == candidates[i-1],则 candidates[i-1] 生成的递归树是 candidates[i] 生成的递归树的子树

40. 组合总和 II

题目链接

python 复制代码
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        res, path = [], []
        candidates.sort()

        def dfs(start: int, target: int) -> None:
            if target < 0:
                return
            if target == 0:
                res.append(path.copy())
            for i in range(start, len(candidates)):
                if i > start and candidates[i] == candidates[i-1]:
                    continue
                path.append(candidates[i])
                dfs(i + 1, target - candidates[i])
                path.pop()
        
        dfs(0, target)
        return res
  • 此题与上题的不同点:每个元素只能使用一次,且原始 candidates 中是存在重复元素的,例如有两个 1,同时选择这两个 1 是没有问题的
  • 回溯之前需添加排序;递归调用从下一个位置开始,即 dfs(i + 1, ...)
相关推荐
萌小丹Fighting2 分钟前
【ArcGIS_Python】使用arcpy脚本将shape数据转换为三维白膜数据
开发语言·python·arcgis
逊嘘19 分钟前
【Java数据结构】了解排序相关算法
数据结构·算法·排序算法
旧故新长42 分钟前
Dijkstra算法解析
算法·图论
linhhanpy1 小时前
自制虚拟机(C/C++)(二、分析引导扇区,虚拟机读二进制文件img软盘)
c语言·汇编·c++·python·stm32·操作系统
_周游1 小时前
【数据结构】_链表经典算法OJ(力扣/牛客第二弹)
数据结构·算法·链表
西农小陈1 小时前
Python-基于PyQt5,wordcloud,pillow,numpy,os,sys的智能词云生成器
开发语言·python·小程序·pycharm·numpy·pyqt·pillow
钓一朵雪1 小时前
【Leetcode刷题记录】45. 跳跃游戏 II--贪心算法
leetcode·贪心算法
LUCIAZZZ1 小时前
Hot100之双指针
java·数据结构·算法
sjsjs112 小时前
【数据结构-前缀树】力扣208. 实现 Trie (前缀树)
数据结构·leetcode
励志成为美貌才华为一体的女子2 小时前
python算法和数据结构刷题[3]:哈希表、滑动窗口、双指针、回溯算法、贪心算法
数据结构·算法·散列表