每日一题算法 : 2020年9月10日[组合总和 II] combinationSum2

2020年9月10日组合总和 II combinationSum2

在这里插入图片描述

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {

    }
}

解题思路:

今天这道题和昨天那道非常类似,区别在于今天这个是不允许重复,但是不允许重复的话这道题会更加简单一些,因为这就变成了单纯的递归+回溯的算法了。

还是昨天的思路,递归的三大关键:

1,流程逻辑

怎么把大问题转变为小问题来解决?

很简单,我们求[1,2,3]能否组成6,那么可以转换为,6-1=[2,3]能否组成5,6-2=[1,3]能否组成4,6-3=[1,2]能否组成2。

2,参数传递

参数的话接收的是一个数组,和要求的值,传出的是能组成target的数组。

3,什么时候停止

target小于等于0的时候应该就需要停止,小于0表示无法组成了,等于0的话是刚好能够组成,在返回值链表中加入一个整形数组,数组中只有一个整数就是当前整数。

代码实现:

在编码过程中逐渐发现了里面埋藏的坑,由于存在重复的数,所以应该先对数组进行处理

在这里插入图片描述

思路出现了问题,想在之前的基础上修改规则就能达到今天的效果,实际上这种强行凑出的方法效率非常低,我为了能够不重复,先进行了一次冒泡排序。

    boolean flag=false;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {

        //先进行排序
        if (!flag)
        {
            paixv(candidates);
        }
        int len=candidates.length;
        //复制数组
        int[] newcandidates=new int[len];
        System.arraycopy(candidates,0 ,newcandidates ,0 ,len );

        List<List<Integer>> res=new ArrayList<>();

        for (int i=0;len>0;){

            ///求得差
            int cha=target-newcandidates[i];

            //如果得到差为0,则在返回值中加入
            if (cha==0){
                List<Integer> list=new ArrayList<>();
                list.add(newcandidates[i]);
                res.add(list);
            }
            //如果小于0,说明不会成立,直接跳过
            //否则开始递归
            else if (cha>0){
                int[] thiscandidates=new int[len-1];
                System.arraycopy(newcandidates,1 ,thiscandidates ,0 ,len-1 );

                //递归
                List<List<Integer>> lists = combinationSum2(thiscandidates, cha);

                //在头部添加一个当前元素
                for (List<Integer> list : lists) {
                    list.add(0,newcandidates[i]);
                }
                res.addAll(lists);
            }
            //删除掉这一个元素
            int val=newcandidates[i];
            do {
                int[] newcandidates2=new int[len-1];
                System.arraycopy(newcandidates,1 , newcandidates2,0 ,len-1);
                len=len-1;
                newcandidates=newcandidates2;
            }while (len!=0&&newcandidates[0]==val);

        }
        return res;
    }

    public void paixv(int[] array){
        int len=array.length;
        for (int i=0;i<len;i++){

            for (int j=0;j<len-1-i;j++){
                if (array[j]>array[j+1]){
                    int val=array[j];
                    array[j]=array[j+1];
                    array[j+1]=val;
                }
            }

        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值