题目:
给定一个数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
思路:和上一题思路很像,不同的是有了重复,同一个数字只能用一次。因此需要注意:
1.取完nums.length-1的数之后,需要return到上一级。
2.重复取,当同一级有相同的数字时,前面相同的那个数字结束调用的时候,包含了后面那个数字的所有情况,因此需要跳过。(这里要思考一下在哪选择跳过,花了我一点时间,在调用完第一个相同数之后的地方调用)。
代码如下:
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> result =new ArrayList<>();
if(candidates==null||candidates.length<1)
{
return result;
}
Arrays.sort(candidates);
backresult(candidates,target,result,new ArrayList<Integer>(),-1);
return result;
}
public void backresult(int[] nums,int target, List<List<Integer>> result,ArrayList<Integer> list,int start)
{
if(target<0)
{
return;
}
if(target==0)
{
result.add(list);
return;
}
//调i的时候,代表i的球已经被调过了,所以如果进行到这里说明这一级所有的球都被找完。
if(start==nums.length-1)
{
return;
}
for(int i=start+1;i<nums.length&&target>=nums[i];i++)
{
list.add(nums[i]);
backresult(nums,target-nums[i],result,new ArrayList<Integer>(list),i);
list.remove(list.size()-1);
while(i<nums.length-1&&nums[i]==nums[i+1])
{
i++;
}
}
}
}