描述
给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。
- 所有的数字(包括目标数字)均为正整数。
- 元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
- 解集不能包含重复的组合。
您在真实的面试中是否遇到过这个题?
样例
给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 ,
解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]
这一题就是上一题的升级版,上一题的解析见:https://blog.csdn.net/wenqiwenqi123/article/details/80195896
那么这一题的不同就是这一次不能重复取数字,同时解集里也不能有重复的。
不能重复取数字容易解决,只要在递归的时候把下标加一就行了。
那么会出现一个什么问题呢?比如C=[1,1,2],T为3的时候,若是用之前的方法,则解集里会有两组解[1,2]与[1,2],第一个解中的1为C中第一个1,第二个解中的1为C中第二个1.为了避免这样的问题,其实只需要两行代码:
class Solution: """ @param candidates: A list of integers @param target: An integer @return: A list of lists of integers """ def combinationSum2(self, candidates, target): # write your code here def search(candidates,target,index,list): if(sum(list)==target): self.result.append(list) return if(index==len(candidates)): return if(sum(list)>target): return for i in range(index,len(candidates)): if(i!=index and candidates[i]==candidates[i-1]): #避免解集中有重复解 continue search(candidates,target,i+1,list+[candidates[i]]) if(len(candidates)==0): return [] self.result=[] list=[] search(sorted(candidates),target,0,list) return self.result s=Solution() print(s.combinationSum2([1,1,2],3))