• LC39.组合总和


    题目表述

    题目连接

    解题思路

    标准的回溯方法模板题,使用回溯三部曲可以解决问题
    回溯三部曲:

    1. 递归函数参数
    2. 递归终止条件
    3. 单层搜索逻辑
    • 这里根据题目的数据范围可以确定,给定的数组中不存在0元素,避免的无限相加的情况。
    • 本题类似于回溯基础中的组合问题,但是与组合问题不同,这里可以重复使用给定数组中的元素。不需要考虑重复的问题。
    • 回溯问题一般都抽象为树形结构,本题抽象成树形结构如下:
      抽象的树形结构
      注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!
      递归三部曲:
    1. 递归函数的参数
      这里依然是定义两个全局变量,二维数组result存放结果集,数组path存放符合条件的结果。
      递归函数的参数可以根据实际的需要来进行设置,无需在一开始就将全部的参数都定义完毕,这里使用了四个参数:
      (1)题目给定的集合candidates。
      (2)目标值target
      (3)数值的总和sum。
      (4)for循环的起始位置,对于组合问题,什么时候需要startIndex呢?如果是一个集合来求组合的话,就需要startIndex,例如:77.组合 (opens new window),216.组合总和III (opens new window)。如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:17.电话号码的字母组合。
    2. 递归终止的条件
      从树形结构中的叶子节点可以清晰看到,终止只有两种情况,sum大于target和sum等于target。sum等于target的时候,需要收集结果。
    3. 单层循环逻辑
      单层for循环从给定的startIndex开始,搜索整个candidates数组。注意本题和77.组合 (opens new window)、216.组合总和III (opens new window)的一个区别是:本题元素为可重复选取的。

    代码(原始)

    ### 解题思路
    此处撰写解题思路
    
    ### 代码
    
    ```java
    class Solution {
    
        List<Integer> path = new LinkedList<>();
        List<List<Integer>> result= new LinkedList<>();
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            callback(candidates, target, 0, 0);
            return result;
        }
    
        int sum = 0;
        private void callback(int[] candidates, int target, int sum, int index) {
            if(sum > target) {
                // 超过指定的目标数字
                return;
            }
            if(sum == target) {
                result.add(new LinkedList<>(path));
                return;
            }
            // 单层循环逻辑
            for (int i = index; i <= candidates.length - 1; i++) {
                sum += candidates[i];
                path.add(candidates[i]);
                // 这里传递索引的时候,不需要加1后再传值,因为数字是可以重复使用的,而不是组合问题。
                // 组合问题不能使用重复的元素,这里可以使用重复的元素
                callback(candidates, target, sum, i);
                // 回溯,移除末尾的元素
                sum -= candidates[i];
                path.remove(path.size() - 1);
    
            }
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    代码(随想录剪枝优化)

    // 剪枝优化
    class Solution {
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> res = new ArrayList<>();
            Arrays.sort(candidates); // 先进行排序
            backtracking(res, new ArrayList<>(), candidates, target, 0, 0);
            return res;
        }
    
        public void backtracking(List<List<Integer>> res, List<Integer> path, int[] candidates, int target, int sum, int idx) {
            // 找到了数字和为 target 的组合
            if (sum == target) {
                res.add(new ArrayList<>(path));
                return;
            }
    
            for (int i = idx; i < candidates.length; i++) {
                // 如果 sum + candidates[i] > target 就终止遍历
                if (sum + candidates[i] > target) break;
                path.add(candidates[i]);
                backtracking(res, path, candidates, target, sum + candidates[i], i);
                path.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    mybatis源码阅读系列(一)
    pip安装报错 RuntimeError:Python version 2.7 or 3.4+ is required——解决办法
    PostgreSQL基于Patroni方案的高可用启动流程分析
    从零开始在window10系统下mysql5.7安装审计插件(亲测绝对可用)
    MySQL ——单行处理函数实例练习
    2022测试岗各大厂面试真题汇总(附带答案解析)
    Apache Tomcat服务器版本号隐藏
    【答辩问题】计算机专业本科毕业设计答辩技巧
    Python网页开发神器fac 0.2.8、fuc 0.1.28新版本更新内容介绍
    淘宝/天猫电商API接口详情
  • 原文地址:https://blog.csdn.net/qq_41705207/article/details/126560452