力扣第40题 中等难度 组合总和II

题目:和39题一样,区别在于每个数在每一组里只能使用一次
思路:
学习第39题的思路,采用递归回溯的方法
需要注意(1,2,7)和(7,2,1)其实属于同一种解,因此如果出现了第二个解的时候,要对其进行排序,排序后判断是否和第一个解一样,如果一样就不放入结果数组。
代码:

//40.组合总和II
public class Solution40 {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        //candidates中的每个数在每个组合中只能用一次
        Arrays.sort(candidates);
        List<List<Integer>> resList = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        find(candidates, target, 0, list, resList);
        return new ArrayList<>(resList);
    }

    //从下标i开始找target,可以用i位置的数,也可以不用,当target为0时,递归结束
    public void find(int[] candidates, int target, int i, List<Integer> list, List<List<Integer>> resList) {
        if (target == 0) {
            //***判断是否已有,比如(1,7)和(7,1)不能同时存在
            //由于按照递归+有序数组的方式,必然前小后大,所以这里先排序再插入
            //不能这么干,因为HashSet判断是否重复依据的是地址,而不是内容。
            List<Integer> list1 = new ArrayList<>(list);
            Integer arr[] = new Integer[list1.size()];
            list1.toArray(arr);
            Arrays.sort(arr);
            //判断是否已有
            boolean yiyou = false;
            for (List<Integer> lis : resList) {
                Integer arrT[] = new Integer[list1.size()];
                lis.toArray(arrT);
                if (arr.length != arrT.length)
                    continue;
                int p;
                for (p = 0; p < arrT.length; p++) {
                    if (arr[p] != arrT[p])
                        break;
                }
                if (p == arrT.length) {
                    yiyou = true;
                    break;
                }
            }
            if (!yiyou)
                resList.add(list1);
            return;
        }
        if (target < 0 || i == candidates.length) {
            return;
        }
        //用i位置的数
        list.add(candidates[i]);
        find(candidates, target - candidates[i], i + 1, list, resList);
        //用完以后去掉1个数(最后一次添加的数)
        list.remove(list.size() - 1);
        //不用i位置的数
        find(candidates, target, i + 1, list, resList);
    }

    public static void main(String[] args) {
        Solution40 s40 = new Solution40();
        s40.combinationSum2(new int[]{2,5,2,1,2}, 5);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值