组合总和 III
难度:
标签:
题目描述
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了。
示例 2:
输入: 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:
输入: k = 4, n = 1 输出: [] 解释: 不存在有效的组合。 在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。
提示:
2 <= k <= 9
1 <= n <= 60
代码结果
运行时间: 32 ms, 内存: 14.8 MB
/*
题目思路:
1. 使用递归回溯的方法找到所有可能的组合。
2. 从1到9选择数字,确保每个数字最多使用一次,并且总和等于n。
3. 使用Java Streams的组合生成和过滤功能来实现。
4. 使用一个辅助函数来进行递归,传递当前组合、剩余的数字、当前的和以及结果列表。
5. 如果当前组合长度等于k并且和等于n,则将该组合加入结果列表。
6. 如果当前和已经大于n或组合长度大于k,则停止搜索。
*/
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CombinationSumIII_Stream {
public List<List<Integer>> combinationSum3(int k, int n) {
return IntStream.rangeClosed(1, 9)
.boxed()
.flatMap(i -> IntStream.rangeClosed(i + 1, 9)
.boxed()
.flatMap(j -> IntStream.rangeClosed(j + 1, 9)
.boxed()
.map(l -> List.of(i, j, l))))
.filter(list -> list.size() == k && list.stream().mapToInt(Integer::intValue).sum() == n)
.collect(Collectors.toList());
}
}
解释
方法:
这个题解使用了回溯算法。它首先定义了候选数字集合candidates为1到9。然后定义了一个辅助函数backtrack,用于生成所有可能的组合。在backtrack函数中,如果当前路径path的长度等于k且路径上数字的和等于n,则找到一个有效组合,将其加入结果列表result中。如果path长度已经大于等于k或者数字和已经大于等于n,则剪枝返回,因为继续搜索也不会找到有效组合。否则,从candidates中当前位置start开始,依次将每个数字加入path,递归调用backtrack,然后再将该数字从path中移除,实现回溯。最后,在主函数中调用backtrack,并返回结果列表result。
时间复杂度:
O(9^k)
空间复杂度:
O(k) + O(C(9,k))
代码细节讲解
🦆
你是如何确定使用回溯算法是解决这个问题的最佳方法?有没有考虑过其他算法?
▷🦆
在backtrack函数中,path列表的长度和数字总和都用于控制递归的终止。请问这种方式是否可能导致一些潜在的有效组合被过早地剪枝掉?
▷🦆
为什么选择候选数字集合为1到9,使用这个范围有什么特别的考虑吗?
▷🦆
题解中提到,每个节点最多有n个子节点,具体是如何实现的?能否详细解释这个回溯树的构建过程?
▷相关问题
组合总和
给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150
个。
示例 1:
输入:candidates =[2,3,6,7],
target =7
输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。 仅有这两种组合。
示例 2:
输入: candidates = [2,3,5],
target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3:
输入: candidates = [2],
target = 1
输出: []
提示:
1 <= candidates.length <= 30
2 <= candidates[i] <= 40
candidates
的所有元素 互不相同1 <= target <= 40