题目
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C 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 target 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
和http://blog.youkuaiyun.com/zl87758539/article/details/51693179类似是它的衍生题目:
区别在哪里呢,首先只能用一次,我想到的办法是加入一个flaglist,如果用过标记为1,没用过标记为0。
以后碰到的时候不管什么时候只要为1就跳过。
不仅还有,还有个问题是,比如这个题目[1,1,…..],两个1 的时候,如果都处理,那么肯定会得到两组一样的结果。
所以这种情况下要排除,在递归的时候,到了这里,需要处理一下。
代码:
class Solution(object):
def combinationSum2(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
self.resList = []
fl = [0]*len(candidates)
candidates = sorted(candidates)#排个序不影响复杂度
self.dfs(candidates,[],target,fl,0)
return self.resList
def dfs(self, candidates, sublist, target, flaglist, last):
if target == 0:
self.resList.append(sublist[:])
if target< candidates[0]:
return
l = None #为了防止重复的比如两个1,那在一层递归只处理一次
for m in range(len(candidates)):
n = candidates[m]
if n > target:
return
if n < last or flaglist[m]==1 or l ==n:
#三种情况:1.因为是从小到大,所以n开始要从上一个数以后,
#2.如果已经使用过,那就继续
#3.如果在这一层递归的时候 比如有两个1, 那之前做一次1的时候,第二次就不处理了,不然会重复
continue
sublist.append(n)
flaglist[m] = 1 #记录是否 用过的
self.dfs(candidates,sublist,target - n,flaglist, n)
flaglist[m] = 0
l = n
sublist.pop()