Problem
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.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
Solution (Java)
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> sums = new ArrayList<>();
// optimize
Arrays.sort(candidates);
combinationSum(candidates, target, 0, sums, new LinkedList<>());
return sums;
}
private void combinationSum(
int[] candidates,
int target,
int start,
List<List<Integer>> sums,
LinkedList<Integer> sum) {
if (target == 0) {
// make a deep copy of the current combination
sums.add(new ArrayList<>(sum));
return;
}
for (int i = start; i < candidates.length && target >= candidates[i]; i++) {
// If candidate[i] equals candidate[i-1], then solutions for i is subset of
// solution of i-1
if (i == start || (i > start && candidates[i] != candidates[i - 1])) {
sum.addLast(candidates[i]);
// call on 'i+1' (not i) to avoid duplicate usage of same element
combinationSum(candidates, target - candidates[i], i + 1, sums, sum);
sum.removeLast();
}
}
}
}
Solution (Javascript)
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum2 = function(candidates, target) {
var res = [];
var len = candidates.length;
candidates.sort((a, b) => (a - b));
dfs(res, [], 0, len, candidates, target);
return res;
};
var dfs = function (res, stack, index, len, candidates, target) {
var tmp = null;
if (target < 0) return;
if (target === 0) return res.push(stack);
for (var i = index; i < len; i++) {
if (candidates[i] > target) break;
if (i > index && candidates[i] === candidates[i - 1]) continue;
tmp = Array.from(stack);
tmp.push(candidates[i]);
dfs(res, tmp, i + 1, len, candidates, target - candidates[i]);
}
};
Explain:
与之前一题不同的地方是:
- 候选数字可能有重复的
- 单个候选数字不能重复使用
Complexity:
- Time complexity : O(n^2).
- Space complexity : O(n^2).