40组合总和II
题目:给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。
说明:所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
来源:https://leetcode-cn.com/problems/combination-sum-ii/
法一:自己的代码
思路:与39组合总和最大的区别是每次回溯时遍历的数组不一样,39中由于数字可以重复使用,所以每次遍历的时候,总是从该数字开始,而40不一样,不可重复所以要加1,从下一个数字开始遍历.
class Solution: def combinationSum(self, candidates, target: int): candidates = sorted(candidates) print(candidates) results = [] def backtrack(a=[], candidates=candidates): if sum(a) == target: results.append(a) return for j,i in enumerate(candidates): # 使用这个前提是要排序 # 画一个树状图便很容易看出,如果连续出现了两个相同的数, # 第二个数再遍历有可能会和第一个数的遍历结果重复 if (j != 0) & (candidates[j] == candidates[j - 1]): continue if sum(a) + i <= target: # 这里candidates[j+1:]是关键,根本原因是因为题中要求所给数组中的每个数字只可以使用一次 # 每次遍历的时候务必只遍历[j+1,)中的数,这样才能保证每个数字只使用一次,类似一往无前法, # 如果j已经到达最大的索引了,说明这轮已经遍历完了, # 传过去的是一个空的list,即下次遍历一个空list也不影响程序 backtrack(a + [i], candidates[j+1:]) # 如果大于了,后面的数也就不用遍历了,因为前面的数小后面的大,小的不行大的一定不行 else: break backtrack() return results if __name__ == "__main__": duixiang = Solution() # a = duixiang.combinationSum([1,1,2],4) # print('u',a) a = duixiang.combinationSum([2,5,3,1,2],5) print('u',a)