eg:输入:k=3,n=9
输出: [[1,2,6],[1,3,5],[2,3,4]]
输入:k=2,n=5
输出:[[1,4][2,3]]
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 """ 4 # @Time : 2019/12/19 21:11 5 6 # @Author : ZFJ 7 8 # @File : k个数的和为n.py 9 10 # @Software: PyCharm 11 """ 12 ''' 13 1.初试化结果列表result=[] 14 15 2.定义回溯函数Flash_back(num,current,tmp,next_sum)其中num表示当前已经使用的数字的数量数,current表示当前访问的数字, 16 tmp表示当前中间结果,next_sum表示下一步的目标和。 17 a.假设num==k,则说明了我们已经使用了k个数; 18 b.假设next_sum==0,则说明tmp的中间结果正好是n,那么我们就可以将tmp加入到result列表中去 19 c.需要注意我们遍历的区间是[current,10),因为只能是0-9之间的正数 20 d.现在我们需要优化,即为传说中的剪枝: 21 1)假如j>next_sum,那么就说明了接下来的数字都比目标和要大,直接break 22 2)执行回溯函数Flash_back(num+1,j+1,tmp+[j],next_sum-j) 23 3.再去执行Flash_back(0,1,[],n) 24 25 4.返回结果列表即可 26 27 28 ''' 29 30 31 class Solution(object): 32 def combinationSum3(self, k, n): 33 """ 34 :type k: int 35 :type n: int 36 :rtype: List[List[int]] 37 """ 38 # 1.定义结果列表 39 result = [] 40 41 # 2.定义回溯函数 42 def Flash_back(num, current, tmp, next_sum): 43 if num == k: 44 if next_sum == 0: 45 result.append(tmp) 46 return 47 for j in range(current, 10): 48 if j > next_sum: 49 break 50 Flash_back(num + 1, j + 1, tmp + [j], next_sum - j) 51 52 Flash_back(0, 1, [], n) 53 return result 54 55 56 a = Solution() 57 b = a.combinationSum3(k=3, n=7) 58 print(b)
个人总结:本体因为用到了回溯法,所以在效率上显得不是很高,在思考,如何改进,欢迎大家一起交流
时间复杂度:因为从头到尾走了一遍,即为O(n!)
空间复杂度:只是借助了列表存储,所以是O(1)