leetcoe39——组合总和——java实现

题目要求:
leetcoe39——组合总和——java实现_第1张图片
分析:
这是一道深度优先遍历算法题目,并且为了避免重复的解,还涉及到剪枝算法。
总体思想我参考了标准答案,网址为:添加链接描述
我把他的图拿过来,这道题目就很清晰明了了,如下所示:
leetcoe39——组合总和——java实现_第2张图片
这个图真的是不要画得太好。剪枝算法就是为了去掉途中绿色框框框起来的部分(它们是重复的),要实现剪枝,首先就得对这个数组中的数字进行排序,使用Arrays.sort()方法即可。
看到这种类似于树的结构,我们条件反射就要想到利用递归。没有递归完的时候,它们剩下的值都是大于0的,而递归完之后,会出现图上所示的两种情况:

  1. 最终结果为负数:这就表明这个结果不是我们想要的,于是我们要把它给丢掉;
  2. 最终结果为0:这个结果是我们想要的,我们把它给存到我们的集合里面去。

在这里,我们需要两个集合:
一个集合拿来存放加起来可能为target的组合,我们将其命名为result,如果组合里加起来不是target,就直接丢掉,如果它加起来是target,那么就要把它给存到我们的大集合里,我们把这个大集合命名为resultList。
还有需要注意的一点是,当我们遍历完之后,我们需要将result中最后的值给去掉。

具体代码如下:

class Solution {
    public List> combinationSum(int[] candidates, int target) {
        List> resultList = new ArrayList<>();
        List result = new ArrayList<>();
        Arrays.sort(candidates);
        compare(candidates, target, 0, result, resultList);
        return resultList;
    }
    private void compare(int[] candidates, int target, int start, List result, List> resultList) {
        if(target < 0) {
            return;
        } else if(target == 0) {
            resultList.add(new ArrayList<>(result));
        } else {
            for(int i = start; i < candidates.length; i++) {
                result.add(candidates[i]);
                compare(candidates, target - candidates[i], i, result, resultList);
                //回溯
                result.remove(result.size() - 1);
            }
        }
    }
}

Tips:在代码中,将result add进resultList集合中时,我们使用的时resultList.add(new ArrayList<>(result)),而不是直接resultList.add(result),这是因为因为result是一个对象的引用,result会因为remove方法而变化,会影响到resultList.

你可能感兴趣的:(leecode)