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

news/2025/2/3 1:49:29 标签: 算法, leetcode, python

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

文章目录

  • 77. 组合
  • 216.组合总和III
  • 17.电话号码的字母组合
  • 39. 组合总和
  • 40. 组合总和 II

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, ...)

http://www.niftyadmin.cn/n/5840415.html

相关文章

todo记事本案例

此案例较为简单&#xff0c;功能需求也比较单一&#xff0c;后续会使用node.jsmysql来进行更加复杂的需求开发的。 主要分为5部分 1、列表渲染 设置好一个数组&#xff0c;使用v-for数组遍历即可 <template> <!-- 主体区域 --> <section id"app&quo…

python-leetcode-二叉搜索树迭代器

173. 二叉搜索树迭代器 - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class BST…

图书管理系统 Axios 源码 __删除图书功能

目录 代码实现&#xff08;index.js&#xff09; 代码解析 使用方法 下面是完整的删除图书功能代码&#xff0c;基于 HTML Bootstrap JavaScript Axios 开发。 代码实现&#xff08;index.js&#xff09; // 删除图书功能 document.querySelector(.list).addEventListen…

Qt常用控件 输入类控件

文章目录 1.QLineEdit1.1 常用属性1.2 常用信号1.3 例子1&#xff0c;录入用户信息1.4 例子2&#xff0c;正则验证手机号1.5 例子3&#xff0c;验证输入的密码1.6 例子4&#xff0c;显示密码 2. QTextEdit2.1 常用属性2.2 常用信号2.3 例子1&#xff0c;获取输入框的内容2.4 例…

CSS 样式化表格:从基础到高级技巧

CSS 样式化表格&#xff1a;从基础到高级技巧 1. 典型的 HTML 表格结构2. 为表格添加样式2.1 间距和布局2.2 简单的排版2.3 图形和颜色2.4 斑马条纹2.5 样式化标题 3. 完整的示例代码4. 总结 在网页设计中&#xff0c;表格是展示数据的常见方式。然而&#xff0c;默认的表格样式…

Python学习——函数参数详解

Python中的函数参数传递机制允许多种灵活的参数类型&#xff0c;可以根据需求灵活配置参数&#xff0c;这使得函数具有更强大的扩展性和适应性。以下是对各类参数类型的详细说明&#xff1a; 1. 定义函数的不同参数类型 1.1 位置参数 定义方式&#xff1a;def func(a, b2) 特…

41【文件名的编码规则】

我们在学习的过程中&#xff0c;写出数据或读取数据时需要考虑编码类型 火山采用&#xff1a;UTF-16 易语言采用&#xff1a;GBK php采用&#xff1a;UTF-8 那么我们写出的文件名应该是何种编码的&#xff1f;比如火山程序向本地写出一个“测试.txt”&#xff0c;理论上这个“测…

【自学笔记】Web前端的重点知识点-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Web前端知识点一、HTML基础二、CSS样式三、JavaScript基础四、前端框架与库五、前端工具与构建六、前端性能优化七、响应式设计与适配八、前端安全 总结 Web前端知识…