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

LeetCode78子集问题中直接赋值ArrayList与新建拷贝赋值的区别是什么

两种列表赋值方式的差异及错误原因解析

本质区别

核心差异为是否生成独立的新列表对象:

  • 第一种写法List<Integer> temp = new ArrayList(arr.get(j)):调用了ArrayList的拷贝构造方法,会在堆内存中创建一个全新的列表对象,新对象会完整复制原列表arr.get(j)的所有元素。后续对temp的所有修改只会作用在这个新列表上,和原列表完全独立,不会影响arr中已经存储的旧子集。
  • 第二种写法List<Integer> temp = arr.get(j):Java中集合属于引用数据类型,变量存储的是对象的内存地址而非对象本身。该写法只是把原列表的内存地址复制给了temp,二者指向堆内存中的同一个列表对象,没有生成新对象。

第二段代码输出异常的原因

子集题的核心逻辑是:遍历已有子集,为每个旧子集追加当前元素生成全新的子集,再将新子集加入结果集,过程中要保证旧子集的内容不被修改。
而第二种写法中,temp.add(nums[i])相当于直接修改了arr中已经存储的旧子集的内容,破坏了原有子集的正确性。同时后续arr.add(temp)存入的还是和旧子集相同的对象引用,后续对该对象的修改会同步影响所有指向该地址的引用,最终会出现大量重复、内容错误的子集。

举个极简的测试用例就能直观看到问题:当输入nums = [1]时

  • 初始arr = [[]]
  • 遍历到i=0时,n=1,j=0:
    直接赋值的写法中,temp拿到的就是arr中第一个空列表的引用,执行temp.add(1)后,arr中原本的空列表就被修改为[1],再执行arr.add(temp)后,arr最终内容为[[1], [1]],和预期的正确结果[[], [1]]完全不符。

内容的提问来源于stack exchange,提问作者Swarna Kanti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:42:03