怎么样写回溯法(从上而下,*代表难点,根据题目而变化)
- 画出递归树,找到状态变量(回溯函数的参数),这一步非常重要 *
- 根据题意,确定结束条件
- 找准选择列表(与函数参数相关),与第一步紧密关联 *
- 判断是否需要剪枝
- 做出选择,递归调用,进入下一层
- 撤销选择
构建递归树,如上图所示,选择列表里的数,都是选择路径(红色框)后面的数,使用一个参数start来标识当前的选择列表的起始位置。也就是标识每一层的状态,所以状态变量是起始位置。
找结束条件:start参数超过边界的时候,程序自己跳过下一层递归了,因此不需要手写结束条件,直接加入结果集。
找选择列表:子集问题的选择列表,是上一条选择路径之后的数
是否需要剪枝:递归树没有重复的,不需要剪枝,也没有不符合条件的。
做出选择和撤销选择:做出选择后进入下一层,后面记得修改成状态即是撤销选择。
仅考虑选择的元素
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
l = len(nums)
ans = []
def backtrack(nums, res, start):
ans.append(res)
for i in range(start, l):
backtrack(nums, res+[nums[i]], i+1)
backtrack(nums,[],0)
return ans
考虑选或不选当前答案
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
l = len(nums)
ans = []
def backtrack(nums, res, start):
if start >= l:
ans.append(res)
return
backtrack(nums, res+[nums[start]], start+1)
backtrack(nums, res, start+1)
backtrack(nums,[],0)
return ans