LeetCode39. 组合总和

题目

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]


分析

这个题被自己点开过不知道多少次了,再不提交了它心里有些过不去。

嗯。。回溯算法,一直递归去求解,把所有组合都遍历一遍,将符合条件的加入到结果集中。

因为是可重复添加,每次遍历数组时都从数组的第一个数开始添加,当添加到货符合或不符合条件时,返回。可能会出现出现重复组合的情况比如[2,2,3],[2,3,2]这种,这是因为不管哪次都是从第一个数字开始遍历添加,增加一个变量,来控制从已经添加过的数字之后添加,嗯。。。说的很不清楚。。。。。。看看代码 

for (int i = 0; i < candidates.length; i++) {
            target -= candidates[i];
            temp.add(candidates[i]);
            help(result,temp,candidates,target);
            temp.remove(temp.size()-1);
            target += candidates[i];
        }

上面这种写法是会出现重复结果的, 原因是因为i每回都从0开始取值,将它改一下改成下面的写法,即可,还要注意n++和n+1的区别,这是不一样的。

for (int i = n; i < candidates.length; i++) {
            target -= candidates[i];
            temp.add(candidates[i]);
            help(result,temp,candidates,target,n++);
            temp.remove(temp.size()-1);
            target += candidates[i];
        }

代码

class Solution {
    public List> combinationSum(int[] candidates, int target) {
        List> result = new ArrayList<>();
        List temp = new ArrayList<>();

        help(result,temp,candidates,target,0);

        return result;
    }
    
    public static void help(List>result, List temp, int[] candidates, int target,int n){

        if (target == 0 ){
            result.add(new ArrayList<>(temp));
            return;
        }
        if (target < 0) {
            return;
        }

        for (int i = n; i < candidates.length; i++) {
            target -= candidates[i];
            temp.add(candidates[i]);
            help(result,temp,candidates,target,n++);
            temp.remove(temp.size()-1);
            target += candidates[i];
        }

    }
    
}


你可能感兴趣的:(算法)