找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
所有数字都是正整数。
解集不能包含重复的组合。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> res = new ArrayList<>();
// 题目要求结果集为 1~9 所以第一个预期数字从1开始
processor(k, n, 1, new ArrayList<>(), res);
return res;
}
public void processor(int k, int n, int cur, List<Integer> path, List<List<Integer>> res) {
// k == 0 说明当前集合已经没有位置了,n <= 0 说明当前结果集大于期望结果 所以当这两个条件满足时可以结束循环
if ( k == 0 || n <= 0) {
// 但是如果 n,k都为0 说明当前结果集就是我们预期想要的结果集,将其加入返回结果中
if (n == 0 && k == 0) {
res.add(new ArrayList<>(path));
}
return;
}
// car > 9 由于题目中要求元素不能大于9 所以大于9违背规则 直接结束循环
// car > n 当前元素超出了我们的计算剩余数 结束循环
// n > 45 题目要求结果集所有元素为 1 ~ 9,1 ~ 9相加为45所以如果n大于45说明当前题目没有正确结果
if (cur > 9 || cur > n || n > 45) {
return;
}
// 从这里开始才是这个循环的第一步
// 将当前元素加入结果集
path.add(cur);
// k - 1 由于已经加入一个元素了,所以剩余元素数-1
// n - car 计算剩余数
// car + 1 计算下一个预期数
// path 当前循环结果集
// res返回值
processor(k - 1, n - cur, cur + 1, path, res);
// 如果当前结果集正好满足条件那么肯定在方法开始部分就已经结束循环了
// 所以能走到这个位置肯定是最后一个元素不满足我们的预期
// 并且这个数字一定小于我们的预期值,所以将最后一个元素移除
int num = path.remove(path.size() - 1);
// 由于方法上面已经判断过各种条件,所以我们直接在调用本方法一次并且把预期数+1即可,减少冗余判断条件
processor(k, n, cur + 1, path, res);
}
}