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); } } }