一个正整数的列表candidates,中间的数字是无序的且有可能有重复,现给定一个正整数的目标target,从candidates中取出若干个数使其和为target,试求所有中可能(重复的不算)
""" 40. Combination Sum II Medium 619 32 Favorite Share Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. Each number in candidates 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. Example 1: Input: candidates = [10,1,2,7,6,1,5], target = 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] Example 2: Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]
拿到这道题目的思路:
首先要给candidates排个序,
将结果分为两类带最后一个数字的和不带最后一个数字的,
但是这样有一个问题就是说如果最后两个数字相同有可能会有重复:解决办法:1,求完以后去重2,事先就去重
我用的第2种方法,假定最后一个数字相同的一定有k个
那么不带最后一个数字的组合中,最后一个数字个数在k-1以内的也包含了也就是重复部分,
我们在此基础上添加一共含有k个最后数字的组合即可
class Solution: def combinationSum2(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ if not candidates: return [] candidates.sort() lenc = len(candidates) if lenc == 1: if target == candidates[0]: return [[target]] result = self.combinationSum2(candidates[0:-1], target) k, lastnum = 0, candidates[-1] for i in range(lenc-1, -1, -1): if candidates[i] == lastnum: k += 1 else: break targetot = target - lastnum*k if targetot == 0: result.append([lastnum]*k) return result elif targetot < 0: return result else: resultot = self.combinationSum2(candidates[:lenc-k], targetot) for i in resultot: result.append(i+[lastnum]*k) return result
这里考虑到一个问题就是排序只要开始排一下就行了,改进一下
class Solution: def sortedCombinationSum2(self, candidates, target): if not candidates: return [] lenc = len(candidates) if lenc == 1: if target == candidates[0]: return [[target]] result = self.sortedCombinationSum2(candidates[0:-1], target) k, lastnum = 0, candidates[-1] for i in range(lenc-1, -1, -1): if candidates[i] == lastnum: k += 1 else: break targetot = target - lastnum*k if targetot == 0: result.append([lastnum]*k) return result elif targetot < 0: return result else: resultot = self.sortedCombinationSum2(candidates[:lenc-k], targetot) for i in resultot: result.append(i+[lastnum]*k) return result def combinationSum2(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ candidates.sort() return self.sortedCombinationSum2(candidates, target)