Leetcode刷题笔记(Python 找出所有相加之和为n的k个组合,组合中只允许含有1-9的正整数,并且每种组合中不存在重复的数字。)

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)

猜你喜欢

转载自www.cnblogs.com/ZFJ1094038955/p/12070382.html