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

递归生成子集时直接推入tmp数组得空结果的原因解析

子集递归代码中tmp与tmp.slice()的差异原因

这段递归求数组子集的代码里,终止条件用res.push(tmp)会输出全空数组,换成res.push(tmp.slice())就能得到正确结果,核心原因是JavaScript里数组是引用类型,具体拆解如下:

  • 数组tmp属于引用类型,程序中所有用到tmp的地方,指向的都是内存里同一个数组实例。递归过程中我们一直在对这个实例做push和pop操作,本质是持续修改同一个数组。
  • 直接执行res.push(tmp)时,res里存储的是这个数组实例的引用,而非当前tmp的内容快照。等整个递归流程走完,tmp会经过多次回溯的pop操作,最终回到初始的空数组状态,此时res里所有元素指向的都是这个空数组,打印出来自然全是空的。
  • 而tmp.slice()会创建一个全新的数组副本,把当前tmp的所有元素复制到这个新数组里,再把新数组的引用存入res。后续对原tmp的修改不会影响到这些已经存入res的副本,所以最终res里保存的是各个递归终止时刻的子集内容,结果完全正确。

举个执行片段的例子:当递归走到pos=3时,tmp是[1,2,3],如果用res.push(tmp),res里存的是这个数组的引用;之后回溯时执行tmp.pop()删掉3,tmp变成[1,2],此时res里的第一个元素也会跟着变成[1,2],直到最后tmp被清空,res里所有元素都变成空数组。但用slice()的话,存的是[1,2,3]的副本,后续tmp怎么修改都不会影响这个副本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:52:13