给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
本题与40. 组合总和II是姊妹题,差别在于元素能否重复使用,这涉及到每次回溯其实元素是否要+1,以及在后面遇到重复元素时如何跳过这个元素。
package 字符串.回溯;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class 组合总和_39 {
static List<List<Integer>>list= new ArrayList<>();
static LinkedList<Integer>linkedlist=new LinkedList<>();
static int sum=0;
static public List<List<Integer>> combinationSum(int[] candidates, int target) {
//从小到大排序,因为后面要判断每次加起来得到的sum是否>target(需要依次变大)
Arrays.sort(candidates);
backtracking(candidates,target,0);
return list;
}
static void backtracking(int[]candidates,int target,int startIndex){
if (sum>target) return;
if (sum==target){
list.add(new ArrayList<>(linkedlist));
return;
}
for (int i = startIndex; i < candidates.length&&sum+candidates[i]<=target; i++) {
sum+=candidates[i];
linkedlist.add(candidates[i]);
//由于每个数字都可以重复使用,因此每次回溯时i不需要+1
backtracking(candidates,target,i);
//归还前将sum减去这个归还的值
sum-=candidates[i];
linkedlist.removeLast();
}
}
public static void main(String[] args) {
int []a={2,3,5};
System.out.println(combinationSum(a,8));
}
}