Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]
[分析] 每个元素可以使用任意多次,求解时就为每个元素枚举使用一次、两次直到其最大次数的情况,下面给出两者递归实现方式,recur1代码简洁些,而recur2效率稍高些,因为减少了递归调用次数,可手动模拟下[1,2],target=3的求解过程就能体会。此题最需注意的是for循环体前面的if判断,作用是避免重复结果,在我做时leetcode 是漏掉了这类test case,我有bug的code成了漏网之鱼~ 看到Code Ganker的解析后意识到了,考虑[1,1],1 这个case帮助理解。
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (candidates == null) return result;
Arrays.sort(candidates);
recur1(candidates, target, 0, new ArrayList<Integer>(), result);
return result;
}
public void recur1(int[] candidates, int target, int start, ArrayList<Integer> oneAns, List<List<Integer>> result) {
if (target <= 0) {
if (target == 0)
result.add((ArrayList<Integer>)oneAns.clone());
return;
}
for (int i = start; i < candidates.length && candidates[i] <= target; i++) {
if (i > 0 && candidates[i] == candidates[i - 1]) continue;
oneAns.add(candidates[i]);
recur(candidates, target - candidates[i], i, oneAns, result);
oneAns.remove(oneAns.size() - 1);
}
}
public void recur2(int[] candidates, int target, int start, ArrayList<Integer> oneAns, List<List<Integer>> result) {
if (target <= 0) {
if (target == 0)
result.add((ArrayList<Integer>)oneAns.clone());
return;
}
for (int i = start; i < candidates.length && candidates[i] <= target; i++) {
if (i > 0 && candidates[i] == candidates[i - 1]) continue;
int maxTimes = target / candidates[i];
for (int j = 1; j <= maxTimes; j++) {
oneAns.add(candidates[i]);
recur(candidates, target - j * candidates[i], i + 1, oneAns, result);
}
for (int j = 1; j <= maxTimes; j++)
oneAns.remove(oneAns.size() - 1);
}
}
}