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

LeetCode子集问题用subsetArr.size()做循环上限内存溢出原因咨询

问题原因分析

核心原因是:内层循环的判断条件如果直接使用subsetArr.size(),会因为循环体内持续向集合新增元素导致size动态增长,循环永远无法终止,最终耗尽内存触发OOM错误。

逻辑细节说明

生成子集的标准迭代逻辑中,遍历每个数字时,我们只需要基于「处理当前数字前已存在的所有子集」生成新子集:即每个旧子集追加当前数字后加入集合,因此内层循环的遍历次数必须是处理当前数字前的固定集合长度。

你贴出的错误代码中,内层循环每一次迭代前都会重新读取subsetArr.size()的最新值,而循环体内每次执行subsetArr.add(takenList)都会让集合长度+1,最终就会出现无限循环。我们可以用最简单的输入nums = [1]验证执行流程:

  1. 初始状态subsetArr = [[]],长度为1
  2. 遍历到num=1,进入内层循环:
    • i=0,判断0 < 1成立,复制空集追加1得到[1],加入集合后subsetArr长度变为2
    • i自增为1,判断1 < 2成立,复制[1]追加1得到[1,1],加入集合后长度变为3
    • i自增为2,判断2 < 3成立,继续生成新元素加入集合,长度持续增长
  3. 循环永远不会结束,直到JVM堆内存被占满抛出内存溢出错误。

修复方案逻辑

你提到的提前定义int size = subsetArr.size()的方案刚好解决了这个问题:每次处理新数字前先将当前集合长度固定下来,内层循环只遍历固定次数,遍历过程中新增的元素不会被纳入当前轮次的遍历范围,刚好符合子集生成的逻辑,不会出现无限循环。修复后的正确代码如下:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> subsetArr = new ArrayList<>();
        subsetArr.add(new ArrayList<>());
        
        for(int num: nums){ 
            // 提前固定当前轮次需要遍历的集合长度
            int size = subsetArr.size();
            for(int i=0; i<size; i++){
                List<Integer> takenList = new ArrayList<>(subsetArr.get(i));
                takenList.add(num);
                subsetArr.add(takenList);
            }
        }
        return subsetArr;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:24:04