回溯法,本质是穷举,是递归的副产品,一般是为了解决组合,排列,子集等问题,下面简单介绍下这三个问题的解题框架。
组合问题:
从n个数中选k个,顺序不重要。
def combine(n, k):
res = []
def backtrack(start, path):
if len(path) == k:
res.append(path[:])
return
for i in range(start, n + 1):
# 剪枝策略:当剩余元素不足以凑满k个数时,提前跳出循环
# for i in range(start, n - (k - len(path)) + 1):
path.append(i)
backtrack(i + 1, path) # 只往后选
path.pop()
backtrack(1, [])
return res
排列问题:
从n个数中排列出所有顺序,顺序重要。
def permute(nums):
res = []
used = [False] * len(nums)
def backtrack(path):
if len(path) == len(nums):
res.append(path[:])
return
for i in range(len(nums)):
if not used[i]:
used[i] = True
path.append(nums[i])
backtrack(path)
path.pop()
used[i] = False
backtrack([])
return res
子集问题:
枚举所有可能的子集,可以为空,可以全选。
def subsets(nums):
res = []
def backtrack(start, path):
res.append(path[:]) # 每个路径都是一个子集
for i in range(start, len(nums)):
path.append(nums[i])
backtrack(i + 1, path)
path.pop()
backtrack(0, [])
return res

88

被折叠的 条评论
为什么被折叠?



