难度中等1152
给定一个无重复元素的数组 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
类似一个分支树,选择或不选,但是会考虑重复选择该数判断和是否能达到target
解答成功:
执行耗时:11 ms,击败了8.72% 的Java用户
内存消耗:39.3 MB,击败了5.41% 的Java用户
class Solution {
List<List<Integer>> res=new ArrayList<>();
public void func(int i,int nums[],List<Integer> sub_list,int target){
//递归条件不超过总长度
if(i==nums.length) return;
//判断sub_list目标数是否达到目标 或者 超出target 则返回
if(target==0){
res.add(sub_list);
return;
}else if(target<0){
return;
}
//不选该数,则跳过选下一个数计算
func(i+1, nums, sub_list, target);
//选择该数,不变位置再尝试继续推断是否符合结果
List<Integer> new_list = new ArrayList<>(sub_list);
new_list.add(nums[i]);
func(i, nums, new_list,target-nums[i]);
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
func(0, candidates, new ArrayList<>(), target);
return res;
}
}
思路二:
解答成功:
执行耗时:3 ms,击败了77.67% 的Java用户
内存消耗:39.2 MB,击败了7.84% 的Java用户
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
List<List<Integer>> res=new ArrayList<>();
public void func(int i,int nums[],List<Integer> sub_list,int target){
//递归条件不超过总长度
if(i==nums.length) return;
//判断sub_list目标数是否达到目标 或者 超出target 则返回
if(target==0){
res.add(sub_list);
return;
}else if(target<0){
return;
}
//for循环是在对每一个值都进行一次所有值筛选的递归
//j==i的目的是:i前面的数递归已经处理考虑过后面的数了,所以当前位置不需要考虑之前的数了
for (int j = i; j < nums.length; j++) {
List<Integer> new_list = new ArrayList<>(sub_list);
new_list.add(nums[j]);
if(target-nums[j]<0) break;//剪枝,因为已经排序了,当前的数已经超过目标值了,后面的没必要再选了
func(j, nums,new_list,target-nums[j]);
}
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);//剪枝需要的前提
func(0, candidates, new ArrayList<>(), target);
return res;
}
}