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

LeetCode 1416 Restore The Array问题:代码无法通过第83个长字符串测试用例的原因分析求助

LeetCode 1416 Restore The Array问题:代码无法通过第83个长字符串测试用例的原因分析求助

嗨,我来帮你拆解下你的C代码和那篇能全过的C++代码之间的核心差异,以及为啥你的代码卡在长字符串测试用例上~

核心问题1:数字构建时的溢出bug(最关键)

你的代码里用atoi转换子字符串来得到数字,但atoi返回的是int类型。当输入字符串里的数字长度接近或超过int的上限(比如32位int最大是2147483647),就会发生溢出,得到错误的数值(比如变成负数或者不符合预期的正数)。这时候你的代码会错误地判断这个数大于k,提前跳出循环,漏掉大量合法的拆分方式,结果自然就错了。

而那篇C++代码用long long类型逐步构建数字(currNum = (currNum * 10) + currDig),long long的范围能到9e18,完全覆盖题目中k的上限(题目里k≤1e9),不会出现溢出,能准确判断数字是否在1到k的合法范围内。

核心问题2:频繁内存分配导致的性能损耗

你的代码在循环里每次都malloc子字符串、memcpy再free,对于超长输入字符串来说,这种频繁的内存操作会带来极大的性能开销,很可能导致超时(尤其是第83个测试用例是大字符串的场景)。而C++代码直接通过字符计算构建数字,不需要额外内存分配,效率高很多。

前导零处理:逻辑没问题但可以优化

你的循环条件里的s[i] != '0'能正确跳过前导零的情况(因为前导零的数字不合法),这部分逻辑和C++代码里currNum <1就break的效果一致。不过可以改成更直观的写法:比如先判断如果s[i] == '0',直接返回0(因为以0开头的数字无法作为合法拆分的一部分),可读性会更好。

给你的代码修改建议

把数字构建改成用long long逐步计算,去掉冗余的内存分配,修改后的dp函数核心循环部分如下:

int dp(char* s, int length, int k, int i, int prevNum) {
    int result;
    if (i == length) {
        return 1;
    }
    if (mem[i] != -1) {
        return mem[i] % MOD;
    }
    result = 0;
    long long num = 0; // 用long long存储当前构建的数字,避免溢出
    // 去掉s[i] != '0'的循环条件,转而在循环内判断前导零
    for (int posLength = 1; posLength <= kLength && posLength <= length - i; posLength++) {
        num = num * 10 + (s[i + posLength - 1] - '0');
        // 数字小于1(比如前导零的情况)或者超过k,直接跳出
        if (num < 1 || num > k) {
            break;
        }
        result = (result + dp(s, length, k, i + posLength, num)) % MOD;
    }
    result %= MOD;
    return mem[i] = result;
}

这样修改后,既解决了溢出问题,又提升了性能,应该就能通过所有测试用例啦~

备注:内容来源于stack exchange,提问作者Sagi Sason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 12:59:30