LeetCode40 组合总数II
题目描述
给定一个数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用一次
样例
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
算法分析
与上一题的区别:本体是限制了选取的次数
int k = u;
while(k < candidates.length && candidates[u] == candidates[k]) k++;
//所以candidates[u]有 k-u个
int cnt = k - u;
时间复杂度
Java代码
class Solution {
static List<List<Integer>> ans = new ArrayList<List<Integer>>();
static void dfs(int[] candidates, int target, int u, int sum, List<Integer> t){
if(sum > target) return;
if(u == candidates.length){
if(sum == target) ans.add(new ArrayList<Integer>(t));
return;
}
int k = u;
while(k < candidates.length && candidates[u] == candidates[k]) k++;
//所以candidates[u]有 k-u个
int cnt = k - u;
for(int i = 0; i <= cnt && sum + candidates[u] * i <= target; i++){
//跳到下一个不同的数字
dfs(candidates, target, k, sum + i * candidates[u], t);
t.add(candidates[u]);
}
for(int i = 0; i <= cnt && sum + candidates[u] * i <= target; i++){
t.remove(t.size() - 1);
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
ans.clear();
List<Integer> t = new ArrayList<Integer>();
dfs(candidates, target, 0, 0, t);
return ans;
}
}