给定一个无重复元素的数组 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]
]
/**
* 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
* candidates 中的数字可以无限制重复被选取。
* @param candidates 无重复元素的数组
* @param target 目标数
* @return 结果集合
*/
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
/**
* 每次将第一个数加入temp序列
* 然后进行搜索
*/
for (Integer i : candidates) {
List<Integer> temp = new ArrayList<>();
temp.add(i);
searchCandidatesToSum(result,temp,i,candidates,target);
temp.remove(i);
}
return result;
}
/**
* 搜索方法
* @param result 结果存放集合
* @param temp 临时结果存放集合
* @param tempSum 临时集合中的数总和
* @param candidates 待搜索数组
* @param target 目标数
*/
private void searchCandidatesToSum(List<List<Integer>> result, List<Integer> temp, int tempSum, int[] candidates, int target) {
/**
* 当总和比目标数大时 不再进行搜索 返回
*/
if( tempSum > target ){
return ;
}
/**
* 当总和等于目标数时
*/
if( tempSum == target ){
/**
* 判断
* 在结果集合中查找是否有重复的集合
* 没有就将当前临时集合转正 加入结果集合中
*/
if(findResult(result, temp)){
temp.sort(Comparator.naturalOrder());
result.add(new ArrayList<>(temp));
}
return;
}
/**
* 每次加入一个数字,然后进行下一层的搜索
* 结束时再将该数字删除,进行下一次的搜索
*/
for (Integer i : candidates) {
temp.add(i);
searchCandidatesToSum(result,temp,tempSum+i,candidates,target);
temp.remove(i);
}
}
/**
* 查找result中是否有temp集合
* @param result 被查集合
* @param temp 要查的集合
* @return 如果存在返回false 不存在返回true
*/
private boolean findResult(List<List<Integer>> result, List<Integer> temp) {
for (List<Integer> item :
result) {
/**
* 当集合大小相同时进行比对
*/
if( item.size() == temp.size() ){
List<Integer> newItem = new ArrayList<>(item);
for (Integer i : temp) {
/**
* 当newItem中存在temp的第i个目标时
* 从newItem中删去当前目标相同的数字
*/
if(newItem.contains(i)){
newItem.remove(i);
}
}
/**
* 若newItem的大小为0时
* 说明newItem与temp的内容完全相同
* 则返回false
*/
if( newItem.size() == 0 ){
return false;
}
}
}
return true;
}