代码与动画 SUBSETS · BACKTRACKING
子集枚举.
选择一个元素后递归深入,再撤销选择,枚举全部子集。
时间 O(n × 2ⁿ)(复制输出)递归空间 O(n)输出空间 O(n × 2ⁿ)
原理与执行逻辑
把当前选择路径视为一个子集,再逐个选择后面的元素递归扩展。返回时撤销刚才的选择,让同一层能够继续尝试其他分支。
执行步骤
- 从空路径与起始下标 0 开始。
- 进入递归时复制当前路径,记录为一个子集。
- 枚举不小于 start 的下标,加入元素并从 i + 1 继续递归。
- 递归返回后弹出该元素,继续尝试下一个下标。
关键理解
路径中的下标严格递增,避免同一集合按不同顺序重复生成。必须复制路径保存输出,才能不受后续撤销影响。
简短示例
[1, 2] 会记录 [],进入选择 1 的分支得到 [1]、[1,2],回溯后选择 2 得到 [2]。
代码与执行动画
STEP 0 / 23function subsets(arr) { const result = [], path = []; function visit(start) { result.push([...path]); for (let i = start; i < arr.length; i++) { path.push(arr[i]); visit(i + 1); path.pop(); } } visit(0); return result;}当前数据正在操作已访问 / 命中标记 / 指针
0
准备回溯
当前路径为空,从下标 0 开始。
配置演示数据
应用后重新生成执行过程,可单步观察结果。
子集枚举的操作规则
输入元素要求互不相同。每层选择递增下标,避免重复生成;空集也包含在输出中。
对应题目与扩展练习
观察执行过程后,按题目约束调整输入、返回值与实现。链接打开官方题目页面。
- 对应题目78. 子集打开题目
直接对应无重复元素的全部子集枚举。