77组合
题目:给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:输入: n = 4, k = 2输出:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]
来源:https://leetcode-cn.com/problems/combinations/
法一:自己的代码 耗时很短,时间上击败了百分之99的代码
思路:关键是剪枝条件的使用,要亲自动手画出树状图进行观察归纳.剪枝的时候要彻底,这就要求归纳出所有的情况.
from typing import List class Solution: def combine(self, n: int, k: int) -> List[List[int]]: # 不用这个内存会小点 # nums = [i+1 for i in range(n)] results = [] def backtrack(a=[],start=0, end=n): # 虽然剪枝了,但是不够彻底,这里剪的是:如果a长度加上后面的要遍历的数的个数恰好是k了, # 即题目要求的,这个时候就直接返回不再遍历了,但是这样剪枝不够彻底,比如要从1到5选4个不重复的数, # 假如先选了1,第二次遍历的数中就不需要选4和5了,因为选也是白选,所以这里就需要剪掉, if len(a) + (end - start) == k: # print('-' * 20) # print(a) # print(range(start,n - (k - len(a)) + 1)) a = a + list(range(start+1, end + 1, 1)) results.append(a) return if len(a) == k: results.append(a) return # 事实上每次需要选哪些数进行遍历,是与a的长度密切相关的,这里明确限定了在a的不同长度下, # 需要遍历哪些数,大大降低了程序的遍历个数,节省了时间 # 注意这里的range中的数比实际遍历的数小1,可以看作是索引,所以backtrack中的start要加1 for i in range(start,n - (k - len(a)) + 1): backtrack(a+[i+1], i+1, end) ## 这里不需要再判断a的长度,因为a的长度是从1往上递增的,一旦等于k就会return,不会出现大于k的情况, # if len(a) < k: # backtrack(a+[i+1], i+1, end) # else: # break backtrack() return results if __name__ == '__main__': duixiang = Solution() a = duixiang.combine(5,3) print(a)