代码随想录 Q70.组合总和 Ⅲ

题目要求:找到和为n的k个数的组合。
思路:k即为树的深度,9为树的宽度(整个集合就只有9个数)。
举例:如果k = 2,n = 4时,就是在集合[1,2,3,4,5,6,7,8,9]中求k = 2,n = 4的组合(k个数,n为和)。
选取过程如下图所示:最后可得结果只有集合(1,3)符合条件。

回溯三部曲:
1.确定递归函数的参数(回溯法中的递归函数参数很难一次性确定下来,一般先写逻辑,需要啥参数了再填什么参数)。
(1)全局变量:result存放结果集,path存放符合条件的结果。
    List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();(2)剩余参数:
-- targetSum(int)目标和,也就是题目中的n。
-- k(int)就是题目中要求的k个数的集合。
-- sum(int)为已经收集的元素的总和,也就是path里元素的总和。
-- startIndex(int)为下一层for循环搜素的起始位置。
private void backTracking(int targetSum, int k, int startIndex, int sum)2.确定终止条件:总共取k个元素,所以如果path.size() == k,就终止。如果此时path收集到的元素和(sum)和targetSum(题目中的n)相同,就用result收集当前的path作为一个结果。
        //剪枝操作if (sum > targetSum) {return;}
        if (path.size() == k) {if (sum == targetSum) result.add(new ArrayList<>(path));return;}3.确定单层搜索的过程:横向遍历for循环就是固定的9个数[1,...,9],因此for循环固定i<=9。处理过程就是path收集每次选取的元素,相当于树形结构里的边,sum来统计path里元素的总和。处理过程要和回溯过程一一对应,处理有加回溯就要有减。

        for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) {path.add(i);sum += i;backTracking(targetSum, k, i + 1, sum);//回溯path.removeLast();//回溯sum -= i;}附代码:
    class Solution {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> combinationSum3(int k, int n) {backTracking(n,k,1,0);return result;}private void backTracking(int targetSum,int k,int startIndex,int sum){//剪枝if(sum > targetSum){return;}if(path.size() == k){if(sum == targetSum){result.add(new ArrayList<>(path));return;}}//剪枝9 - (k - path.size()) + 1for(int i = startIndex;i <= 9 - (k - path.size()) + 1;i++){path.add(i);sum += i;backTracking(targetSum,k,i + 1,sum);//回溯path.removeLast();//回溯sum -= i;}}
}