问题描述
Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
Each number in candidates may only be used once in the combination.
给你一个正整数数组candidates
和目标值target
。
使用数组中的元素凑齐target
,数组中的元素仅能使用一次,请计算一共有多少中唯一的组合方式?
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
举个例子:
类似题目:
[39] Combination Sum
[90] Subsets II
Update at 2020_0907
来看下示意图:
再来看下完整实现:
class Solution {
List<List<Integer>> ans = new LinkedList<>();
private void dfs(int[] cands, int t, LinkedList<Integer> child, int u, int sum, boolean[] used){
if (sum == t){
ans.add(new LinkedList<>(child));
return;
} else if (sum > t){
return;
}
for (int i = u; i < cands.length; i++){
if (used[i] || i > 0 && cands[i] == cands[i - 1] && !used[i - 1]) continue;
used[i] = true;
child.add(cands[i]);
dfs(cands, t, child, i + 1, sum + cands[i], used);
child.removeLast();
used[i] = false;
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
int n = candidates.length;
var used = new boolean[n];
dfs(candidates, target, new LinkedList<>(), 0, 0, used);
return ans;
}
}
解法1
说下思路:
首先,避免重复统计,需要对原始数组进行升序
排列。
然后,由于原始数组中的元素只能使用一次,所以递归函数中cur = i + 1
。
接着,终止条件和 [39] Combination Sum 这道题一致。
最后,为了避免重复统计,需要加个判断,和 [39] Combination Sum 一样。
if (i > cur && num == candidates[i - 1]){
continue;
}
来看下实现:
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> ans = new LinkedList<>();
bt(candidates, target, ans, new LinkedList<>(), 0);
return ans;
}
private void bt(int[] candidates, int remain,
List<List<Integer>> ans, LinkedList<Integer> child, int cur){
if (remain == 0){
ans.add(new LinkedList<>(child));
} else if (remain < 0){
return;
}
for (int i = cur; i < candidates.length; i++){
int num = candidates[i];
if (i > cur && num == candidates[i - 1]){
continue;
}
child.add(num);
bt(candidates, remain - num, ans, child, i + 1);
child.removeLast();
}
}
}
Enjoy it !
一位喜欢提问、尝试的程序员
(转载本站文章请注明作者和出处 姚屹晨-yaoyichen)