You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode 78子集问题Python代码append操作异常排查

LeetCode 78「子集」Python实现异常排查

错误复现

原实现代码如下,输入长度为1的数组(如[1])时输出符合预期,输入长度大于1的数组时,sol.append(temp[i])未正确追加当前值,反而导致sol中已存储的原有元素被意外修改:

def solution(arr):
    sol=[[]]
    temp=[[]]
    for num in arr:
        for i in range(len(temp)):
            temp[i].append(num)
            sol.append(temp[i])          
        temp=sol.copy()
    return sol

问题根因

异常由Python列表的引用机制+两个逻辑错误共同导致:

  • 浅拷贝未复制嵌套子列表:temp=sol.copy()执行的是浅拷贝,仅会创建新的顶层列表对象,列表内存储的所有子列表(即各个子集)和原sol中的子列表指向同一个内存地址。后续修改temp[i]时,sol中存储的对应子列表因为是同一个对象,会被同步修改,这就是原有元素被意外篡改的直接原因。
  • 原地修改旧子集而非生成新子集:遍历到新数字时,正确逻辑应该是基于上一轮的旧子集,生成「旧子集+当前数字」的全新列表对象,但代码直接对temp[i]调用append(num),属于原地修改已经存入结果的旧子集,根本没有生成新的子集。

输入长度为1的数组时结果看似正常,是因为第一轮循环结束后才第一次执行temp拷贝,还未触发后续轮次的引用共用问题;一旦数组长度超过1进入第二轮循环,引用篡改的问题就会直接暴露。例如输入[1,2]时,第二轮处理数字2,执行temp[0].append(2)时,sol中最初存储的空列表会被同步改成[2],直接破坏之前的计算结果。

修正后实现

核心调整为:每轮遍历新数字时,基于已有子集复制生成全新的列表对象,全程不修改已经存入结果集的子集,代码如下:

def solution(arr):
    sol = [[]]
    for num in arr:
        new_subsets = []
        # 遍历当前已生成的所有子集
        for subset in sol:
            # 复制原子集,拼接当前数字得到全新子集,不修改原有对象
            new_sub = subset.copy()
            new_sub.append(num)
            new_subsets.append(new_sub)
        # 将本轮新生成的子集全部追加到结果集
        sol.extend(new_subsets)
    return sol

也可以用列表切片subset[:]替代subset.copy(),效果完全一致,写法更简洁。

内容的提问来源于stack exchange,提问作者Rishi Preetham Karpurapu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:12:29