第7章|回溯与搜索
Unit 01 · LeetCode #78
← Unit 00
78
SubsetsBacktracking · start · Power Set
子集没有固定终点:
每个搜索节点本身就是答案。
path 表示当前子集,start 限制下一层只能向更大的索引扩展。进入调用先保存快照,再执行选择、递归与撤销。
题目要求
给定一个元素互不相同的整数数组 nums,返回所有可能的子集。答案不能包含重复子集,顺序任意。
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
pass
- 空集和原集合自身都属于答案;
- 若输入长度为
n,答案数量为2ⁿ; - 元素互不相同,因此无需处理同层值去重。
示例与主模型
nums = [1,2,3]
输出可为:
[[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
start + for 模型中,每个节点表示一个已选子集。候选窗口为 [start,n),选择 index 后进入 index+1。
记录时机进入每个调用立即执行
result.append(path.copy())。唯一顺序索引严格递增,同一组元素只生成一次。
完整覆盖每个节点记录,所有合法扩展继续向下。
状态恢复
append → recurse → pop 后兄弟分支看到同一父状态。检测到已保存进度
完整演示看懂状态如何变化
功能提示槽位只保留作用/语义
关键代码补全用代码恢复算法骨架
独立完成迁移到新题
nums = [1,2,3] 的状态空间树
绿色下沿:当前节点本身可记录橙色:当前状态黄色:当前可选状态
当前递归契约
当前 path[]
当前 start0
可用候选1, 2, 3
当前动作记录快照
共享路径 path
候选窗口 [start,n)
result 中的快照
已访问节点1 / 8
已记录子集1 / 8
当前深度0
候选窗口[0,3)
状态是否干净是
关键槽位补全先选槽位 → 再选代码
待填槽位|只提示作用/语义
待选代码标签|顺序随机
每次必须先点击左侧一个槽位,再点击右侧代码标签。选中后会立即拼进右侧代码骨架;再次选择同一槽位可以替换。
from typing import List
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
def backtrack(start: int) -> None:
result.append(path.copy())
for index in range(start, len(nums)):
path.append(nums[index])
backtrack(index + 1)
path.pop()
backtrack(0)
return result
实时拼接后的代码骨架0 / 6
当前认知焦点随运行步骤变化
current
visited
path
start
代码 × 状态逐行联动代码 / path / start / result / 搜索树同步
状态依赖问题
本环节已完成
页面会保留当前状态,观察完成后再手动进入下一环节。