在一个集合里找出大小为k的组合(77题)
给一个字符串,有几种切割的方式,满足一定的条件
一个集合有几个满足一定条件的子集
组合没有顺序,但排列有顺序,12和21是不同的
n皇后,数独
要多画图,抽象为树形结构:
树的宽度一般为回溯的集合的大小,用for来遍历,
树的深度是递归的深度
def backtracking(参数):
if (终止条件):
存放结果(收集结果)
return
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)):
处理节点
backtracking(路径,选择列表)#递归
回溯,撤销处理结果
题目链接:组合
这题最后发生的错误事backtracking(n,k,(i+1))
写的是backtracking(n,k,(index+1))
。
n=4,k=2
如果i=1,那么剩下的区间就是[2,3,4],这里没什么问题
i=2,那么剩下的区间就是[3,4]
i=3,剩下的区间就是[4]
如果用backtracking(n,k,(index+1))
,那么剩下的区间就一直都是[2,3,4]。
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
path = []
result = []
def backtracking(n,k,index):
if len(path) == k:
result.append(path[:])
return
for i in range(index,(n+1)):
path.append(i)
backtracking(n,k,(i+1)) #这不是index+1
path.pop()
backtracking(n,k,1)
return result
这个题可以节省的空间其实是,假设n=4, k=4。
如果i=1,那么剩下的区间就是[2,3,4],这里没什么问题
i=2,那么剩下的区间就是[3,4],那么已经全选上都不到四个元素了
i=3,剩下的区间就是[4],这个也一样。
所以2,3根本不用做。
l e n ( p a t h ) + ( n + 1 − i ) ≥ k → i ≤ n + 1 + l e n ( p a t h ) − k len(path)+(n+1-i) \geq k \rightarrow i \leq n+1+len(path)-k len(path)+(n+1−i)≥k→i≤n+1+len(path)−k
i ≤ n − ( k − l e n ( p a t h ) ) + 1 i \leq n-(k-len(path))+1 i≤n−(k−len(path))+1
所以应该变成for i in range(index,(n-(k-len(path))+2)):
+2因为pyhton的range是不包括最后一个值的。
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
path = []
result = []
def backtracking(n,k,index):
if len(path) == k:
result.append(path[:])
return
for i in range(index,(n-(k-len(path))+2)):
path.append(i)
backtracking(n,k,(i+1)) #这不是index+1
path.pop()
backtracking(n,k,1)
return result