给定一个无重复元素的数组 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]
]
提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate
中的每个元素都是独一无二的。1 <= target <= 500
利用回溯法的思想,因为题目的要求是从candidates数组中找出可重复的几个数,然后让他们的和相加为target 。我们可以将问题一步一步分解为子问题,挨个遍历这个candidates数组,先选择一个数字candidates[i],让target 减去t,然后再在candidates数组中找出可以相加等于target -candidates[i]的数,然后重复…… 直到target为0,则我们找到了一种组合,如果在寻找过程中,target<0,说明此路不通,我们回溯到上一层,重新选择数字。
我们在回溯的过程中,如何可以剪去一下分支的话,可以大大提高效率,可以剪枝的几种情况:
class Solution {
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
getResult(result, new ArrayList<>(), candidates, target, 0);
return result;
}
private static void getResult(List<List<Integer>> result, List<Integer> cur, int candidates[], int target, int start) {
if (target == 0) {
result.add(new ArrayList<>(cur));
return;
}
for (int i = start; i < candidates.length; i++) {
if (target < candidates[i])
continue;
cur.add(candidates[i]);
getResult(result, cur, candidates, target - candidates[i], i);
cur.remove(cur.size() - 1);
}
}
}