Leetcode - Combination Sum II

[分析] 输入数组中的每个元素至多使用一次,相较于Combination Sum,需要做两个小改动,改动虽小但很关键。改动1是在向下递归时传下去的start是下一个元素的下标,这保证每个元素至多只被使用一次。改动2是for循环体前面的if判断,这个判断的作用是避免出现重复结果,虽然每个元素不能被重复使用,但重复出现在结果中是允许的(考虑[1,1], 2),因此限定只对第一次得到某个数进行递归(i > start 而不是 i > 0, 条件设为 i > 0 会fail @[1,1],2),接下来就跳过这个数,因为在同一层递归中,for循环的每个元素在结果中处于相同位置,若不跳过则会出现重复结果,考虑[1,1,1],3 进行体会。
参考Code Canker的解析 http://blog.csdn.net/linhuanmars/article/details/20829099,并补充上自己的理解。

[url]
public class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        Arrays.sort(candidates);
        recur(candidates, target, 0, new ArrayList<Integer>(), result);
        return result;
    }
    public void recur(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 > start && candidates[i] == candidates[i - 1])
                continue;
            oneAns.add(candidates[i]);
            recur(candidates, target - candidates[i], i + 1, oneAns, result);
            oneAns.remove(oneAns.size() - 1);
        }
    }
}
[/url]

猜你喜欢

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