力扣算法:组合总和II

原题链接:https://leetcode-cn.com/problems/combination-sum-ii

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。 

这个题目与上一个题目基本相似,只是不能重复使用税数字了。所以根据上一题的代码,尝试修改,将起点位置修改为i+1。尝试执行。

public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> daan = new ArrayList<>();
        backtrack(result,candidates,target,daan,0,0);
        return result;
    }

    //回溯算法
    public void backtrack(List<List<Integer>> result,int[] candidates, int target,List<Integer> daan,int sum ,int start  ){
        if(sum == target){
            result.add(new ArrayList<Integer>(daan));
            return;
        }
        if(sum>target){
            return;
        }

        for(int i=start;i<candidates.length;i++){
            if(sum+candidates[i]<=target){
                daan.add(candidates[i]);
                backtrack(result,candidates,target,daan,sum+candidates[i],i+1);
                daan.remove(daan.size()-1);
            }

        }

    }

执行之后,发现当给定数组中有重复数字的时候可能会出现重复结果,所以思考如何去重。

我使用了一个set 集合,将符合条件的结果进行排序之后,和set集合内的进行比较,如果有则跳过,没有则放到结果集,和set集合中。

代码如下:

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> daan = new ArrayList<>();
        Set<ArrayList<Integer>> chongfu= new HashSet<>();
        backtrack(result,candidates,target,daan,0,0,chongfu);
        return result;
    }

    //回溯算法
    public void backtrack(List<List<Integer>> result, int[] candidates, int target, List<Integer> daan, int sum , int start , Set<ArrayList<Integer>>  chaongfu){
        if(sum == target){

       //这部分为去重的内容。 List
<Integer> ans=new ArrayList<Integer>(daan); //不能直接使用daan ,因为这样修改的其中顺序,下边的结果将会出错。 Collections.sort(ans); if(!chaongfu.contains(ans)){ result.add(new ArrayList<Integer>(ans)); chaongfu.add(new ArrayList<Integer>(ans)); } return; } if(sum>target){ return; } for(int i=start;i<candidates.length;i++){ if(sum+candidates[i]<=target){ daan.add(candidates[i]); backtrack(result,candidates,target,daan,sum+candidates[i],i+1,chaongfu); daan.remove(daan.size()-1); } }
原文地址:https://www.cnblogs.com/wys-373/p/13697768.html