• 39-组合总和(回溯法)


    思路:

    思路:根据示例 1:输入: candidates = [2,3,6,7],target = 7。

    候选数组里有 2 ,如果找到了 7 - 2 = 5 的所有组合,再在之前加上 2 ,就是 7 的所有组合;
    同理考虑 3,如果找到了 7 - 3 = 4 的所有组合,再在之前加上 3 ,就是 7 的所有组合,依次这样找下去;
    上面的思路就可以画成下面的树形图。

    去重复
    在搜索的时候,需要设置搜索起点的下标 begin ,由于一个数可以使用多次,下一层的结点从这个搜索起点开始搜索;
    在搜索起点 begin 之前的数因为以前的分支搜索过了,所以一定会产生重复。

    剪枝提速
    如果一个数位搜索起点都不能搜索到结果,那么比它还大的数肯定搜索不到结果,基于这个想法,我们可以对输入数组进行排序,以减少搜索的分支;

    排序是为了提高搜索速度,非必要;

    搜索问题一般复杂度较高,能剪枝就尽量需要剪枝。把候选数组排个序,遇到一个较大的数,如果以这个数为起点都搜索不到结果,后面的数就更搜索不到结果了。

    class Solution {//回溯法
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> res =new ArrayList<>();
            Arrays.sort(candidates);
            backpack(res,candidates,target,0,new ArrayList<Integer>());
            return res;
        }
        public void backpack(List<List<Integer>> res,int [] candidates,int target,int i,List<Integer> tmp)//i是搜索起点的下标,因为数字可以重复选取,下一层的结点从这个搜索起点开始搜索;这个起点之前的一定被搜索过了,所以不需要
        {
            if(target==0)
            {
                res.add(new ArrayList<>(tmp));
                return;
            }
            if(target<0) return;
            for(int start=i;start<candidates.length;start++)//一轮循环,找的是tmp里加入了candidates[start]的所有组合。下一轮,找的是,tmp里加入candidates[start+1](candidates[start]不加,因为带这个数的所有组合都找到了)的所有组合。
            {
               // if(target<0)break;
                tmp.add(candidates[start]);
                backpack(res,candidates,target-candidates[start],start,tmp);
                tmp.remove(tmp.size()-1);
            }
        }
    }

      

    作者:liweiwei1419
    链接:https://leetcode-cn.com/problems/combination-sum/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-2/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    python
    weui 问题
    Mac 问题
    ORM存储过程和实体类代码生成工具
    说说QQ空间SEO
    用户体验走嘴和走心的区别
    一切不以用户为中心的O2O 都是耍流氓
    10分钟制作自己的手机QQ
    一无所有其实没什么
    别人的鞋不一定合脚
  • 原文地址:https://www.cnblogs.com/lzh1043060917/p/12761663.html
Copyright © 2020-2023  润新知