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

使用ListNode实现两数相加时触发Java堆内存溢出问题排查

两数相加ListNode Demo内存溢出问题分析

核心问题定位

你遇到的java.lang.OutOfMemoryError: Java heap space确实和最后一个while循环直接相关,同时代码还存在其他隐性bug,逐一分析如下:

1. 结果链表构建逻辑错误(OOM直接诱因)

在addTwoNums方法的最后while循环中:

while(i < resultString.length()){
    resultLN.val = Integer.parseInt(String.valueOf(resultString.charAt(i)));
    resultLN.next = resultLN;
    i ++;
}

这段代码的问题是:每次循环都将resultLN的next指向自身,最终生成的是一个自循环的单节点链表,并没有创建多个节点来存储结果的每一位。

当后续调用toString方法时,toString里的循环会无限执行:

while(next != null){
    value.append(next.val);
    next = next.next;
}

因为next永远指向当前节点自身,循环永远不会终止,StringBuffer会不断扩容,最终耗尽Java堆内存,抛出内存溢出异常。

2. toString方法破坏原链表结构

ListNode的toString方法中,直接修改了当前节点的next成员变量:

while(next != null){
    value.append(next.val);
    next = next.next;
}

遍历完成后,当前节点的next会被置为null,原链表的结构被永久破坏,后续无法再正常遍历该链表。

3. 大数溢出风险

你通过将链表转成字符串再转成Integer的方式计算总和,当链表长度超过Integer的取值范围(最大为2^31-1,即10位数字)时,会直接抛出NumberFormatException,这不符合两数相加题目的设计初衷——题目本意就是处理无法用普通整数类型存储的大数。

修正方案

修正结果链表构建逻辑

正确的做法是逐个创建新节点,构建正常的单链表:

int i = 0;
ListNode dummy = new ListNode();
ListNode current = dummy;
while(i < resultString.length()){
    int val = Integer.parseInt(String.valueOf(resultString.charAt(i)));
    current.next = new ListNode(val);
    current = current.next;
    i ++;
}
return dummy.next;

修正toString方法

避免修改原节点的next指针,使用临时变量遍历:

public String toString(){
    StringBuffer value = new StringBuffer();
    ListNode current = this;
    while(current != null){
        value.append(current.val);
        current = current.next;
    }
    return value.toString();
}

推荐:逐位相加的正确实现(避免大数溢出)

按照题目要求,直接遍历两个链表的节点,逐位相加并处理进位,不需要转成整数:

public static ListNode addTwoNums(ListNode l1, ListNode l2){
    ListNode dummy = new ListNode();
    ListNode current = dummy;
    int carry = 0;
    while(l1 != null || l2 != null || carry > 0){
        int sum = carry;
        if(l1 != null){
            sum += l1.val;
            l1 = l1.next;
        }
        if(l2 != null){
            sum += l2.val;
            l2 = l2.next;
        }
        carry = sum / 10;
        current.next = new ListNode(sum % 10);
        current = current.next;
    }
    return dummy.next;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:07:43