题目:Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations inC where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5]
and target8
,
A solution set is:
[ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
思路:递归回溯
需要注意的是:
1、在同一层递归树中,如果某元素已经处理并进入下一层递归,那么与该元素相同的值就应该跳过。否则将出现重复。
例如:1,1,2,3
如果第一个1已经处理并进入下一层递归1,2,3
那么第二个1就应该跳过,因为后续所有情况都已经被覆盖掉。
2、相同元素第一个是需要进行所有递归的,比如1,1,2,3,如果目标是2,那么1,1是满足条件,如果所有相同的去掉,那么会遗漏解。
也就是说对相同的元素,只对第一个进行递归处理,其余的不进行递归。
同时对于不重复的元素,只能出现一次,不能多次出现;对于重复出现n次的数字,只能出现0~n次。
代码:
public class Solution {
List<List<Integer>> ret=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>(); //链表一定要new出对象,否则只是引用
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
if(candidates == null) return null;
Arrays.sort(candidates);
DFS(0,0,target,candidates);
return ret;
}
void DFS(int start,int sum,int target,int[] candidates )
{
if(sum==target)
{
ret.add(new ArrayList<>(tmp)); //添加的时候,一定要用tmp链表重新new一下,否则没有数据
return;
}
else if(sum> target ) return;
else
{
for(int i=start ;i < candidates.length;i++)
{
if(i != start && candidates[i] == candidates[i-1])
continue;
tmp.add(candidates[i]);//添加数据
DFS( i+1, sum+candidates[i],target,candidates);
tmp.remove(tmp.size()-1); //remove 是用index去掉数据
}
}
}
}