组合总和 II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
/*
思路:将查找数字组合拆分成两个子问题——第一个数和查找组合剩余的数,大问题的解就是将两个小问题的
结果放在一个out集合中。
找到第一个数后递归往后查找数字组合,剩余数是从第一个数的下一个位置开始继续找。
递归终止条件:当目标值小于0时,就不用找了;当目标值等于0时,组合符合条件添加到结果中
*/
//对数组升序排序,这样当找到一个数目标值小于0时,证明后面的数也都会使目标值小于0是不符合要求的
Arrays.sort(candidates);
List<Integer> out=new LinkedList<>();
List<List<Integer>> result=new LinkedList<List<Integer>>();
findOneNum(candidates,0,target,out,result);
return result;
}
private void findOneNum(int[] nums,int start,int target,List<Integer> out,List<List<Integer>> result)
{
if (target<0)
{
return;
}else if (target==0)
{
//out就是符合条件的一组数据,创建新集合存储添加到结果中,因为每次都是使用out存储新的组合不能让结果所有元素都指向out
result.add(new ArrayList<Integer>(out));
return;
}
for (int i = start; i < nums.length; i++) {
out.add(nums[i]);
findOneNum(nums,i+1,target-nums[i],out,result);
/*当findOneNum返回时代表找完了一组数,准备从下一个数查找其他组数据,下一个数作为其他组数据
的第一个数如果和当前的第一个数相同就不用找了
*/
while (i<nums.length-1 && nums[i]==nums[i+1])
{
i++;
}
out.remove(out.size()-1);
}
}