回溯leetcode41.组合总和Ⅱ

题目:

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

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

注意:解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

这道题区别于之前的几篇文章的是canidates数组中存在相同的数字,这就可能使解集中存在相同的集合,所以这道题主要就是要去重。下面记录一下去重过程。

关于去重,是避免最终的输出解集中出现相同的集合,至于解集的子集中是可以出现相同元素的,而这里的相同只是数字相同,并不是同一个位置的元素。

用visited数组来标记每个元素是否被访问过。

如下图:

注意:在进行去重前一定要对canidates数组进行升序排列,目的是把相同的数字放在一起(剪枝时也会用到),因为如果前后相同的话,后面的数字的所有情况已经包含在它之前的与他相同的数字的所有情况里面了,后面数字的所有情况就不用进行判断了。

代码如下:

class Solution {
     List<List<Integer>> result = new ArrayList<List<Integer>>();
     List<Integer> list = new ArrayList<Integer>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
       
        boolean[] visited  = new boolean[candidates.length];
        //排序
        Arrays.sort(candidates);
        backtracking(candidates,target,visited,0,0);
        return result;
    }
    public void backtracking(int[] candidates,int target,boolean[] visited,int sum,int startIndex){
        if(sum > target){
            return;
        }
        if(sum == target){
            result.add(new ArrayList<Integer>(list));
            return;
        }
        for(int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++){
            //去重
            if(i > 0 && candidates[i] == candidates[i - 1] && !visited[i - 1]){
                continue;
            }
            list.add(candidates[i]);
            visited[i] = true;
            backtracking(candidates,target,visited,sum + candidates[i],i + 1);
            //回溯
            list.remove(list.size() - 1);
            visited[i] = false;

    }

}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值