今天开始回溯
回溯的模板。for循环是横向遍历,backtracking为纵向遍历。
回溯法解决的问题都可以抽象为树形结构,树的宽度为集合的大小,树的深度为递归的深度
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
77. 组合
未剪枝
class Solution:
def __init__(self):
self.result = []
self.path = []
def backtracking(self, n, k, startIndex):
if len(self.path) == k:
self.result.append(self.path[:])
return
for i in range(startIndex, n+1):
self.path.append(i)
self.backtracking(n, k, i+1)
self.path.pop()
def combine(self, n: int, k: int) -> List[List[int]]:
self.backtracking(n, k, 1)
return self.result
剪枝,主要在于如果剩下的数量+path中的数量不够K个了,那就停止循环遍历
class Solution:
def __init__(self):
self.result = []
self.path = []
def backtracking(self, n, k, startIndex):
if len(self.path) == k:
self.result.append(self.path[:])
return
for i in range(startIndex, n-(k-len(self.path))+2):
self.path.append(i)
self.backtracking(n, k, i+1)
self.path.pop()
def combine(self, n: int, k: int) -> List[List[int]]:
self.backtracking(n, k, 1)
return self.result