LeetCode-【数组】- 组合总和 II

版权声明:转载注明出处就可以了。。。 https://blog.csdn.net/zw159357/article/details/82312992

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

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

说明:

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

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

题解:很容易想到用深搜遍历所有的情况,但在这里需要注意的问题是,数组本身的元素是有重复的,两个相同的数组元素与其它元素组合组成的满足要求的解相同的,如示例1:[1,7]和[7,1]是相同的解。那么接下来的问题就是避免重复解的问题了,我的思路是先将数组排序,当每次递归开始的元素与其前一个元素相同时,直接跳过,这样就避免重复使用相同元素开始组成解了。接下来就是对整个递归进行优化了,当目标值target减去某一个数组值后小于0时,就可以直接跳过了。

class Solution {
    static List<List<Integer>> res;
    public static void dfs(int[] candidates,List<Integer> tmp,int target,int s){
        if(target<0)
            return;
        if(target==0){
            res.add(new ArrayList<>(tmp));
            return ;
        }
        for(int i=s;i<candidates.length;i++){   
            if(candidates[i]>target||(i>s&&candidates[i]==candidates[i-1]))
                continue;
            tmp.add(candidates[i]);
            dfs(candidates,tmp,target-candidates[i],i+1);
            tmp.remove(tmp.size()-1);
        }
    }
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        res=new ArrayList<>();
        dfs(candidates,new ArrayList<>(),target,0);
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/zw159357/article/details/82312992