递归求数组子集:Python中sub类f2方法执行原理问询
递归生成子集的f2方法详解
这段Python代码靠递归生成数组的所有子集,核心逻辑全在f2方法里,下面拆解它的工作机制和执行流程:
一、f2的核心思路
f2有两个参数:
curr:当前正在拼凑的子集s1:还没处理的原数组元素
递归的核心就是对每个元素做二选一:不把它加入当前子集,或者把它加进去,最后把两种选择的结果拼起来,就是所有可能的子集。
看代码细节:
def f2(self,curr,s1): if s1: return self.f2(curr,s1[1:]) + self.f2(curr + [s1[0]], s1[1:]) return [curr]
- 当
s1不为空(还有元素没处理):self.f2(curr,s1[1:]):跳过s1的第一个元素,直接处理剩下的部分,当前子集curr不变(对应“不选当前元素”的选择)。self.f2(curr + [s1[0]], s1[1:]):把s1的第一个元素加到curr里,再处理剩下的部分(对应“选当前元素”的选择)。- 把这两个递归调用的结果拼接成一个列表,就是包含当前元素选与不选的所有子集。
- 当
s1为空(所有元素都处理完了):返回[curr]——把当前拼凑好的子集包装成列表返回,这是递归的终止条件,避免无限调用。
二、执行流程的树形示意图
拿原数组[1,2]举例子,用树形结构看整个递归过程:
初始调用:f2([], [1,2]) ├─ 分支1(不选1):f2([], [2]) │ ├─ 子分支1(不选2):f2([], []) → 返回 [[]] │ └─ 子分支2(选2):f2([2], []) → 返回 [[2]] │ → 分支1结果:[[]] + [[2]] = [[], [2]] └─ 分支2(选1):f2([1], [2]) ├─ 子分支1(不选2):f2([1], []) → 返回 [[1]] └─ 子分支2(选2):f2([1,2], []) → 返回 [[1,2]] → 分支2结果:[[1]] + [[1,2]] = [[1], [1,2]] → 最终结果:分支1 + 分支2 = [[], [2], [1], [1,2]]
每一层递归都会把问题拆成“选当前元素”和“不选当前元素”两个小问题,直到所有元素都处理完,再把所有结果逐层合并,最终得到完整的子集列表。
三、结合主代码的运行逻辑
主代码里循环输入元素,每次添加一个元素后就调用sub().f1(a)生成当前数组的子集:
- 比如先输入n=1,再输入元素1,此时数组是
[1],递归会生成[[], [1]]; - 再输入元素2,数组变成
[1,2],就会生成上面例子里的所有子集。
内容的提问来源于stack exchange,提问作者Waqar
相关产品推荐
相关产品推荐

