美文网首页
40.组合总和 II

40.组合总和 II

作者: justonemoretry | 来源:发表于2020-07-14 00:05 被阅读0次

自己解法

标准的回溯加剪枝,思路很清晰,但是在细节上出了点小问题,一个是递归的时候应该用i+1,用成了start + 1。还有就是这个重复的剪枝,一开始没想明白,画了下树形图,就是减去相邻树枝中重复的部分,这个一定要放到回溯操作后,放在前面的话会导致不同层的相同元素也被过滤。

class Solution {

    List<List<Integer>> output = new ArrayList<>();

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {

        Arrays.sort(candidates);

        List<Integer> res = new ArrayList<>();

        dfs(candidates, target, 0, res);

        return output;

    }

    public void dfs(int[] candidates, int target, int start, List<Integer> res) {

        if (target == 0) {

            output.add(new ArrayList(res));

            return;

        }

        for (int i = start; i < candidates.length; i++) {

            if (target < candidates[i]) {

                return;

            }

            res.add(candidates[i]);

            dfs(candidates, target - candidates[i], i + 1, res);

            res.remove(res.size() - 1);

            // 减去重复的枝

            while (i < candidates.length - 1  && candidates[i + 1] == candidates[i]) {

                i++;

            }

        }

    }

}

官方解法

查看比较多的这个解法,剪重复的枝,是在前面剪的,不过是i > index以后,也就是在同层遍历的时候进行剪枝。

class Solution {

    public List<List<Integer>> result = new LinkedList<>();

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {

        if(candidates.length == 0){

            return result;

        }

        Arrays.sort(candidates);

        comSum2(candidates,target,0,new LinkedList<Integer>());

        return result;

    }

    public void comSum2(int[] candidates, int target, int index, LinkedList<Integer> trace){

        //满足结束条件

        if(target == 0){

            result.add(new LinkedList(trace));

            return ;

        }

        if(target > 0){

            //选择列表,并加上约束

            for(int i = index; i<candidates.length; i++){

                //如果以当前结点为头结点的所有组合都找完了,那么下一个与他他相同的头结点就不用去找了。

                if(i > index && candidates[i] == candidates[i - 1]) continue;

                //做出选择

                trace.add(candidates[i]);

                comSum2(candidates,target - candidates[i],i+1,trace);

                //撤销选择

                trace.removeLast();

            }

        }

    }

}

相关文章

网友评论

      本文标题:40.组合总和 II

      本文链接:https://www.haomeiwen.com/subject/guuthktx.html