1,问题描述
216. 组合总和 III
难度:中等
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
1 2 3 4 5
| 输入: k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了。
|
示例 2:
1 2 3 4 5 6 7
| 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]] 解释: 1 + 2 + 6 = 9 1 + 3 + 5 = 9 2 + 3 + 4 = 9 没有其他符合的组合了。
|
示例 3:
1 2 3 4
| 输入: k = 4, n = 1 输出: [] 解释: 不存在有效的组合。 在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。
|
提示:
2,初步思考
模式识别:k个数字、目标为n,可以转变为以选定一个数字num之后,(k-1)个数字、目标为(n-num)这个是典型的子问题
我自己想到的是递归处理
3,代码处理
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| import java.util.ArrayList; import java.util.List;
public class _216组合总和III {
List<Integer> temp = new ArrayList<Integer>(); List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> combinationSum3(int k, int n) { for (int mask = 0; mask < (1 << 9); ++mask) { if (check(mask, k, n)) { ans.add(new ArrayList<Integer>(temp)); } } return ans; }
public boolean check(int mask, int k, int n) { temp.clear(); for (int i = 0; i < 9 && temp.size() < k; ++i) { if (((1 << i) & mask) != 0) { temp.add(i + 1); } } if (temp.size() != k) { return false; } int sum = 0; for (int num : temp) { sum += num; } return sum == n; }
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum3_recursive(int k, int n) { recursive(k, n, 9, new ArrayList<>()); return res; }
private void recursive(int k, int n, int max, List<Integer> list) { if (n == 0 && k == 0) { res.add(new ArrayList<>(list)); return; } else if (n < 0 || max <= 0) { return; } while (max >= 1) { list.addLast(max); recursive(k - 1, n - max, --max, list); list.removeLast(); } }
public static void main(String[] args) { _216组合总和III combinationSum3 = new _216组合总和III(); System.out.println(combinationSum3.combinationSum3(3, 9)); } }
|