Leetcode - Combination Sum

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

猜你喜欢

转载自likesky3.iteye.com/blog/2232037