leetcode 40. Combination Sum II

题目
罗列出满足要求的全部组合,并且每个元素只能用一次。
dfs+回溯

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        HashSet<List<Integer>> set = new HashSet<>();
        if(candidates.length==0) return new ArrayList<>(set);
        Arrays.sort(candidates);
        dfs(set,new ArrayList<>(),candidates,target,0);
        return new ArrayList<>(set);
    }
    public void dfs(HashSet<List<Integer>> set,List<Integer> list,int[] num,int target,int pos){
        if(target<0) return;
        if(target==0){
            set.add(new ArrayList<>(list));
        }
        for(int i=pos;i<num.length;i++){
            if(num[i]>target) break;
            list.add(num[i]);
            dfs(set,list,num,target-num[i],i+1);
            list.remove(list.size()-1);
        }
    }
}

也可以不用set,只需要加上一句判断当前元素是否与之前元素相等,如果相等那么就跳过。因为对于相同的元素,第一次出现的时候就已经与后面的元素把所有的可能都组合了,就不需要再来一次。
例如1 1 2 3
第一个1已经与23组合过了,那么就可以跳过第二个1。
要明白跳过这一步骤是针对于同一层循环的,并不妨碍两个1出现可行解。因为此时两个1是处于不同层的循环出现的,并不冲突。

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        if(candidates.length==0) return res;
        Arrays.sort(candidates);
        dfs(res,new ArrayList<>(),candidates,target,0);
        return res;
    }
    public void dfs(List<List<Integer>> res,List<Integer> list,int[] num,int target,int pos){
        if(target<0) return;
        if(target==0){
            res.add(new ArrayList<>(list));
        }
        for(int i=pos;i<num.length;i++){
            if(num[i]>target) break;
            if(i>pos && num[i]==num[i-1]) continue;
            list.add(num[i]);
            dfs(res,list,num,target-num[i],i+1);
            list.remove(list.size()-1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值