二哥的 LeetCode 刷题笔记-040 组合总和②
二哥说,今天去帮父亲干了半天的活,一身尘埃,但是感觉很充实,累但知道了生活的不易,更需要去珍惜现在拥有的一切,所以马不停蹄地继续刷题,今天的题目是组合总和 II,这道题目是一道中等难度的题目,但是,只要我们细心分析,就能迎刃而解。
题意
给定一个候选人编号的集合 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
难度
中等
示例
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
分析 1
很显然,这道题和 039.组合总和 是姊妹篇。不过,这道题要求同一个数字不能被重复选择,但是candidates
中可能会存在有重复的数字。
同样我们也可以使用暴力,枚举所有的可能性,然后判断是否符合条件,如果符合条件就加入到答案中。
class Solution04001 {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(candidates); // 排序以便于后续处理
generateAllCombinations(candidates, target, new ArrayList<>(), result, 0);
return result;
}
private void generateAllCombinations(int[] candidates, int target, List<Integer> combination, List<List<Integer>> result, int start) {
int sum = combination.stream().mapToInt(Integer::intValue).sum();
if (sum > target) {
return;
}
if (sum == target) {
if (!result.contains(combination)) {
result.add(new ArrayList<>(combination)); // 创建组合的副本并添加到结果列表
}
return;
}
for (int i = start; i < candidates.length; i++) {
combination.add(candidates[i]);
generateAllCombinations(candidates, target, combination, result, i + 1); // 每个数字只能使用一次,所以递归从 i+1 开始
combination.remove(combination.size() - 1); // 回溯,撤销最后的选择
}
}
public static void main(String[] args) {
Solution04001 solution = new Solution04001();
int[] candidates = {10, 1, 2, 7, 6, 1, 5};
int target = 8;
真诚点赞 诚不我欺
回复