• LeetCode回溯算法组合问题——216.组合总和III


    一、题目描述:

    216. 组合总和 III

    找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

    • 只使用数字1到9
    • 每个数字 最多使用一次 

    返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

     

    二、分析


    1.本题是一个经典的回溯算法题目,怎么辨别题解需要使用回溯算法呢? 

    回溯法,一般可以解决如下几种问题:

    • 组合问题:N个数里面按一定规则找出k个数的集合
    • 切割问题:一个字符串按一定规则有几种切割方式
    • 子集问题:一个N个数的集合里有多少符合条件的子集
    • 排列问题:N个数按一定规则全排列,有几种排列方式
    • 棋盘问题:N皇后,解数独等等

    2.回溯法模板

    回溯三部曲:

    (1)返回值以及参数

    返回值一般为void。再来看一下参数,因为回溯算法需要的参数可不像二叉树递归的时候那么容易一次性确定下来,所以一般是先写逻辑,然后需要什么参数,就填什么参数

    (2)回溯函数终止条件

    什么时候达到了终止条件,一般来说搜到叶子节点了,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归

    (3)回溯搜索的遍历过程。

    for循环是横向遍历可以理解一个节点有多少个孩子,这个for循环就执行多少次

    backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。

    总结回溯算法模板如下:

    1. void backtracking(参数) {
    2. if (终止条件) {
    3. 存放结果;
    4. return;
    5. }
    6. for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
    7. 处理节点;
    8. backtracking(路径,选择列表); // 递归
    9. 回溯,撤销处理结果
    10. }
    11. }

    3.代码

    和77.组合http://t.csdn.cn/VUS9I一样,依然需要一维数组path来存放符合条件的结果,二维数组result来存放结果集。

    这里我依然定义path 和 result为全局变量。

    接下来还需要如下参数:

    • targetSum(int)目标和,也就是题目中的n。
    • k(int)就是题目中要求k个数的集合。
    • sum(int)为已经收集的元素的总和,也就是path里元素的总和。
    • startIndex(int)为下一层for循环搜索的起始位置。

    代码为:

    1. class Solution {
    2. List<List<Integer>> result = new ArrayList<>();
    3. LinkedList<Integer> path = new LinkedList<>();
    4. public List<List<Integer>> combinationSum3(int k, int n) {
    5. backTracking(n, k, 1, 0);
    6. return result;
    7. }
    8. private void backTracking(int targetSum, int k, int startIndex, int sum) {
    9. // 减枝
    10. if (sum > targetSum) {
    11. return;
    12. }
    13. if (path.size() == k) {
    14. if (sum == targetSum) result.add(new ArrayList<>(path));
    15. return;
    16. }
    17. // 减枝 9 - (k - path.size()) + 1
    18. for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) {
    19. path.add(i);
    20. sum += i;
    21. backTracking(targetSum, k, i + 1, sum);
    22. //回溯
    23. path.removeLast();
    24. //回溯
    25. sum -= i;
    26. }
    27. }
    28. }


     

  • 相关阅读:
    【简单、高效、性能好】SetFit:无需Prompts的高效小样本学习
    Docker 安装
    基于智能优化算法的交通流模拟器(Matlab代码实现)
    evm 代码分析
    MATLAB算法实战应用案例精讲-【深度学习】SEnet注意力机制
    让 Java 打包缩小一大半,Solon v1.9.3 发布
    [附源码]SSM计算机毕业设计足球队管理系统JAVA
    verdi -play选项加载settings,执行一些自定义的初始化Verdi命令
    软件测试面试题:Internet采用哪种网络协议?该协议的主要层次结构?Internet物理地址和IP地址转换采用什么协议?
    使用AutoFS服务完成自动挂载
  • 原文地址:https://blog.csdn.net/w20001118/article/details/125618991