子集递归算法在Python与C++中的表现差异及问题排查
子集生成算法Python与C++表现差异原因及修正方案
差异原因
- 参数传递机制差异
- C++中
get_set函数的res参数是值传递,每次递归调用都会创建全新的vector副本,各个递归分支对res的修改完全独立,不会互相干扰。 - Python中列表属于可变对象,
get_subsets的temp参数使用了可变默认值[],而Python的默认参数只会在函数定义时初始化一次。同时递归传递的是列表的引用,所有递归分支都在操作同一个列表对象,导致最终结果被多次修改,出现异常。
- C++中
- 初始结果集的问题
Python代码中初始化self.result = [[]],后续递归中append的temp可能和这个初始空列表是同一个引用,最终会被后续的append操作修改,导致结果错误。
修正后的Python代码
写法一:使用列表副本传递
from typing import List class Solution: def __init__(self): self.result = [] def get_subsets(self, arr, temp, index=0): if index == len(arr): self.result.append(temp) return top = arr[index] index += 1 # 传递temp副本,忽略当前元素 self.get_subsets(arr, temp.copy(), index) # 创建新列表并加入当前元素,传递新列表 new_temp = temp.copy() new_temp.append(top) self.get_subsets(arr, new_temp, index) def subsets(self, nums: List[int]) -> List[List[int]]: self.get_subsets(nums, []) return self.result
写法二:通过列表拼接创建新对象(更简洁)
from typing import List class Solution: def __init__(self): self.result = [] def get_subsets(self, arr, temp, index=0): if index == len(arr): self.result.append(temp) return top = arr[index] index += 1 # 忽略当前元素,直接传递原temp self.get_subsets(arr, temp, index) # 加入当前元素,通过拼接创建新列表传递 self.get_subsets(arr, temp + [top], index) def subsets(self, nums: List[int]) -> List[List[int]]: self.get_subsets(nums, []) return self.result
修改说明
- 移除了
get_subsets中temp的可变默认参数,改为在subsets调用时传入空列表[],避免默认参数仅初始化一次的问题。 - 每次递归时传递独立的列表对象(要么用
copy()生成副本,要么用temp + [top]创建新列表),确保各个递归分支的修改互不影响。 - 初始化
self.result为空列表,递归结束时会自动包含空集(所有元素都被忽略的分支),无需提前添加。
内容的提问来源于stack exchange,提问作者Srijan Singh
相关产品推荐
相关产品推荐

