LeetCode Hot 100 No.39 组合总和

本文探讨了一种改进的回溯算法,针对组合问题如何高效地生成不包含重复组合的解。通过设置一个index跟踪已遍历元素,确保在后续搜索时跳过已存在的组合,从而降低时间复杂度。

在这里插入图片描述
思路:
看到所有组合,就想到回溯法。
但是普通的回溯法并不能让解集中不包括重复组合。
如candidates=[2, 3, 6, 7] ,target = 7
如果用普通的回溯法,{3, 2,2} {2,3 ,2} {2,2 ,3} 都会放入解集中。
如果每次生成一个解,就去解集中查找有没有重复的,那样时间复杂度过高。
找解集的过程可以看做四个步骤

  1. 找到以2开头的所有解
  2. 找到以3开头的所有解
  3. 找到以6开头的所有解
  4. 找到以7开头的所有解
    在第2步的时候,我们需要找到以3开头的所有解,这时候解集中已经存在{2, 2, 3}了。但是如果我们再从头开始遍历candidates数组,这样2又会加入到当前的解,{3, 2,。。。} 这样就会找到{3, 2,2} ,但是和{2,2,3}就重合了,所以当我们开始找3开头的解的时候,就不能再将3以前的元素加入解中。只能从3,6,7开始遍历。
    我们用一个index来记录上一趟递归已经遍历到的元素下标,然后这次循环就从当前index开始,不去考虑index之前的元素。
class Solution {
    List<List<Integer>> ans = new ArrayList<List<Integer>>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        findall(candidates,target,new ArrayList<Integer>(),0);
        return ans;
        
        
    }

    public void findall(int[] candidates, int target, ArrayList<Integer> route,int index)
    {
        if(target==0)
        {
            ans.add(new ArrayList<>(route));
            return;
        }

        for(int i = index;i<candidates.length;i++)//每次从index开始遍历
        {
            if(target-candidates[i]<0)
                continue;
            target -= candidates[i];
            route.add(candidates[i]);
            findall(candidates,target,route,i);
            route.remove(route.size()-1);
            target += candidates[i];
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值