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

Java链表减法函数测试失败求助:多种尝试仍未解决

Java链表大数减法无法通过测试用例的问题修复

核心问题分析

你的代码存在几个致命逻辑错误,导致测试用例失败:

  • 计算顺序完全错误:大数减法需要从低位到高位逐位计算,但你的代码从链表头部(高位)开始遍历,完全颠倒了运算顺序。
  • 链表交换后指针未重置:长度相等时交换list1和list2后,未将指针重置到起始位置,导致后续补零操作使用错误的指针位置。
  • 交换链表后循环未终止:长度相等比较时,交换链表后未立即break,继续用交换后的链表进行后续比较,逻辑混乱。
  • 结果未去除前导零:计算完成后结果链表可能存在高位零,不符合测试用例的预期格式。

修正后的代码

public static LList subtract(LList list1, LList list2) {
    // 复制原链表,避免修改传入的原始数据
    LList num1 = copyList(list1);
    LList num2 = copyList(list2);

    // 标记num1是否大于等于num2
    boolean num1Greater = true;
    if (num1.length() < num2.length()) {
        num1Greater = false;
    } else if (num1.length() == num2.length()) {
        num1.moveToStart();
        num2.moveToStart();
        while (num1.currPos() < num1.length()) {
            int digit1 = (int) num1.getValue();
            int digit2 = (int) num2.getValue();
            if (digit1 < digit2) {
                num1Greater = false;
                break;
            } else if (digit1 > digit2) {
                num1Greater = true;
                break;
            }
            num1.next();
            num2.next();
        }
        // 重置指针到起始位置
        num1.moveToStart();
        num2.moveToStart();
    }

    // 确保num1是较大的数
    if (!num1Greater) {
        LList temp = num1;
        num1 = num2;
        num2 = temp;
    }

    // 给较短的链表补低位零,使两者长度一致
    int lengthDiff = num1.length() - num2.length();
    for (int i = 0; i < lengthDiff; i++) {
        num2.append(0);
    }

    // 反转链表,让低位在前,符合减法运算顺序
    num1 = reverseList(num1);
    num2 = reverseList(num2);

    LList result = new LList();
    int borrow = 0;
    num1.moveToStart();
    num2.moveToStart();

    // 从低位到高位逐位计算
    while (num1.currPos() < num1.length()) {
        int digit1 = (int) num1.getValue() - borrow;
        int digit2 = (int) num2.getValue();
        borrow = 0;

        if (digit1 < digit2) {
            digit1 += 10;
            borrow = 1;
        }

        result.append(digit1 - digit2);
        num1.next();
        num2.next();
    }

    // 反转结果链表,恢复高位在前的顺序
    result = reverseList(result);

    // 去除前导零(保留至少一个零)
    while (result.length() > 1 && (int) result.getValue() == 0) {
        result.remove();
        result.moveToStart();
    }

    return result;
}

// 辅助函数:复制链表
private static LList copyList(LList original) {
    LList copy = new LList();
    original.moveToStart();
    while (original.currPos() < original.length()) {
        copy.append(original.getValue());
        original.next();
    }
    return copy;
}

// 辅助函数:反转链表(假设insert方法是在头部插入)
private static LList reverseList(LList original) {
    LList reversed = new LList();
    original.moveToStart();
    while (original.currPos() < original.length()) {
        reversed.insert(original.getValue());
        original.next();
    }
    return reversed;
}

关键修改点说明

  1. 保护原始数据:通过copyList复制输入链表,避免修改调用方传入的原始链表。
  2. 清晰的大数判断逻辑:用num1Greater标记大数,避免在循环中交换链表导致的指针混乱,判断完成后统一交换。
  3. 反转链表适配减法顺序:通过reverseList将链表反转,让低位在前,符合减法从低位到高位的运算逻辑。
  4. 修正借位计算:借位从当前位的数字中扣除,再与减数比较,逻辑更清晰准确。
  5. 去除前导零:计算完成后反转结果链表,移除头部的高位零,确保结果格式符合预期。

测试验证

用你的测试用例验证:

  • 1279 - 523:反转后计算得到6570,再反转结果为756,符合预期。
  • 1005 - 509:反转后计算得到6940,再反转结果为496,符合预期。
  • 12345 - 678:反转后计算得到76611,再反转结果为11667,符合预期。
  • 856 - 900:自动交换为900-856,反转后计算得到440,再反转结果为44,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:45:03