LeetCode216-组合总和III

题目链接

英文链接:https://leetcode.com/problems/combination-sum-iii/

中文链接:https://leetcode-cn.com/problems/combination-sum-iii/

题目详述

找出所有相加之和为 nk 个数的组合组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

  • 所有数字都是正整数。
  • 解集不能包含重复的组合。

示例 1:

1
2
输入: k = 3, n = 7
输出: [[1,2,4]]

示例 2:

1
2
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

题目详解

依旧是 DFS,回溯即可。总结一下这类排列组合的题目。

  • 枚举每一个可能的元素。
  • 进入下一层将当前元素加入临时集合中(也有可能是置访问标志为 true 等操作)。
  • 递归进入下一层。
  • 恢复原状。
  • 递归的终止条件是满足条件退出,或者不可能再符合条件退出(剪枝)。

排列与组合的区别在于:

  • 求排列数一般从头开始枚举。
  • 求组合数一般要传入一个起始下标,记录从哪里开始枚举。

重复与不重复的区别在于:

  • 可以重复意味着传入下一层的起始下标一般不用加 1,直接传入。
  • 不能重复意味着传入下一层的起始下标一般要加 1 才可以传入,并且在操作之前还要跳过重复元素(有时需要首先对给定数组进行排序),这些都是为了避免重复。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class LeetCode_00216 {

public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> res = new ArrayList<>();
dfs(k, n, 1, res, new ArrayList<>(k));
return res;
}

private void dfs(int k, int n, int s, List<List<Integer>> res, ArrayList<Integer> list) {
if (list.size() == k) {
if (n == 0) {
res.add(new ArrayList<>(list));
}
return;
}
for (int i = s; i <= 9; ++i) {
list.add(i);
dfs(k, n - i, i + 1, res, list);
list.remove(list.size() - 1);
}
}
}