LeetCode40. 组合总和 II(回溯+剪枝)

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

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

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

对比39题,唯一的区别在于解集不能重复,因此对比39题我们要考虑到使用used数组来保证不会产生相同结果

(117条消息) LeetCode39.组合总数(回溯与剪枝)_m0_51630248的博客-CSDN博客

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        int len=candidates.length;
        List<List<Integer>>ans=new ArrayList<>();
        List<Integer>path=new ArrayList<>();
        Arrays.sort(candidates);
        boolean[]used=new boolean[len];
        dfs(ans, path,used,candidates,target,0,0);
        return ans;
    }
    void dfs(List<List<Integer>>ans,List<Integer>path,boolean[]used,
        int[]candidates,int target,int sum,int start){//下标从start开始
        if(sum>target){
            return;
        }else if(sum==target){
            ans.add(new ArrayList<>(path));
        }
        for(int i=start;i<candidates.length;i++){//保持答案内部的有序性
            if(i>0&&candidates[i]==candidates[i-1]&&!used[i-1])continue;
            sum+=candidates[i];
            path.add(candidates[i]);
            used[i]=true;
            dfs(ans, path,used,candidates, target,sum,i+1);
            used[i]=false;
            sum-=candidates[i];
            path.remove(path.size()-1);
        }
    }
}

核心是这句话

if(i>0&&candidates[i]==candidates[i-1]&&!used[i-1])continue;

 作用多多,遍历的时候如果前一个数相同则直接跳过,但注意到如果前一个数字使用还是可以重用的,注意到!used[i-1]去掉就会产生这样的结果,就是因为1,1相同,遍历时直接跳过第二个1,这显然是错误的,因此要注意这句话,非常之精髓,非常之重要啊老铁们!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值