classSolution: defcombine(self, n: int, k: int) -> List[List[int]]: result = [] self.backtracking(n,k,1,[],result) return result
defbacktracking(self,n,k,index,path,result): iflen(path) == k: result.append(path[:]) # 注意path的拷贝方式 return for i inrange(index,n+1): path.append(i) self.backtracking(n,k,i+1,path,result) #这里改成index+1会返回所有组合(包括重复的) path.pop()
剪枝
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defcombine(self, n: int, k: int) -> List[List[int]]: result = [] self.backtracking(n,k,1,[],result) return result
defbacktracking(self,n,k,index,path,result): iflen(path) == k: result.append(path[:]) # 注意path的拷贝方式 return for i inrange(index,n-(k-len(path))+2): # 这里的n-(k-len(path))+2是为了剪枝,因为如果n-(k-len(path))+2还小于k,那么就没有必要继续遍历了 path.append(i) self.backtracking(n,k,i+1,path,result) #这里改成index+1会返回所有组合(包括重复的) path.pop()
解释一下这个剪枝的地方: need = k - len(path),i一直到n,共有n-i+1个元素,剩余元素至少要大于等于need才行,因此n-i+1 >= need,即n-i+1 >= k - len(path),即n-(k-len(path))+1 <= n,但是python的range是左闭右开的,右边取不到,所以要+1变成n-(k-len(path))+2
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9 每个数字 最多使用一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: defcombinationSum3(self, k: int, n: int) -> List[List[int]]: result = [] self.backtracking(n,k,0,1,[],result) return result defbacktracking(self,targetsum,k,cursum,index,path,result): if cursum > targetsum: return iflen(path) == k : if targetsum == cursum: result.append(path[:]) return for i inrange(index,9-(k-len(path))+2): cursum += i path.append(i) self.backtracking(targetsum,k,cursum,i+1,path,result) cursum -= i path.pop()