leetcode 39. 组合总和 中等 回溯

题目:
在这里插入图片描述

分析:数字组合的问题,组合出符合目标值的所有情况,所有数字都可以重复使用,很容易想到使用回溯(深度遍历)来做解决。以第一个示例为例,从2开始,减去2后目标变成5,那么就要求出能组合成5的组合,加上一开始的2就组成以2开头的所有解;如果从3开始,目标变成4,接下来就要求出能组合成4的组合;以此类推,画图画出一棵树会好理解很多。
要注意的点:
1.先对可取值进行排序,升序排列,这样可以方便判断解的组合是否重复且方便剪枝
2…停止回溯的条件:目标值变成0,即已经找到一种解法,添加到结果,返回。
3.剪枝。如果当前值大于目标值,那么往后的值都不用考虑了,因为后面的值更大
4.下一次考虑求解的起始值,因为每个值都可重复使用,所以下一次考虑求解的起始值跟上一个相同,再考虑后面的值(再之前的值不考虑了,因为在之前的值比上一个小,由于是深度比遍历的做法,所以之前一定考虑过了)

代码:

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(candidates, target, 0, path, result);
        return result;
    }

    public void dfs(int[] candidates, int target, int begin, List<Integer> path, List<List<Integer>> result){
        if(target == 0){
        	//这里要new一个,因为path是引用,如果直接添加引用,后面引用变化了,里面的值也会变化
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i = begin; i < candidates.length; i++){
        	//剪枝
            if(target - candidates[i] < 0){
                break;
            }
            path.add(candidates[i]);
            dfs(candidates, target-candidates[i], i, path, result);
            path.remove(path.size()-1);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

发布了134 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_40208575/article/details/104723480