回溯的一般格式
path = [ ]
res = [ ]
def backtracking(param) {
if (end condition):
save result
return
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点
backtracking(路径,选择列表)
回溯,撤销处理结果
}
}
组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
res = []
path = []
def func(n:int, k:int, startIndex:int):
if len(path) == k:
res.append(path[:])
return
for i in range(startIndex, n+1):
path.append(i)
func(n, k, i+1)
path.pop()
func(n,k,1)
return res
剪枝
已经选择的元素个数:path.size();
还需要的元素个数为: k - path.size();
在集合n中至多要从该起始位置 : n - (k - path.size()) + 1,开始遍历
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
tmp ,res = [], []
def func(StartIndex, n ,k):
if len(tmp) == k:
res.append(tmp[:])
return
for i in range(StartIndex, n-(k-len(tmp))+2): # 优化的地方
tmp.append(i)
func(i+1, n, k)
tmp.pop()
func(1,n,k)
return res
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字 1 到 9
每个数字 最多使用一次
class Solution:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
def backtracking(start, sum_now):
if sum_now > n:
return
if len(path) == k and sum_now == n: # key_point
res.append(path[:])
return
for i in range(start, 9-(k-len(path))+2): # key_point
path.append(i)
sum_now += i # key_point
backtracking(i+1, sum_now)
sum_now -= i # key_point
path.pop()
res, path = [], []
backtracking(1,0)
return res
全排列
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res = []
def backtrack(nums, tmp):
if not nums:
res.append(tmp)
return
for i in range(len(nums)):
backtrack(nums[:i]+nums[i+1:], tmp+[nums[i]])
backtrack(nums, [])
return res