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

C#递归引发内存不足异常:求解LeetCode K-th Symbol in Grammar遇阻

解决「第K个语法符号」问题的内存溢出优化方案

你的代码触发内存不足异常,核心问题是直接生成了完整的超长字符串。当A=30时,字符串长度为2^(30-1)=536870912,光是这个字符串就需要500MB以上的内存空间,再加上递归过程中产生的大量中间字符串,内存必然撑爆。

问题规律拆解

这道题完全不需要生成完整字符串就能得出结果,核心规律如下:

  • 第n行的第k个字符,由第n-1行的第(k+1)//2个字符决定(整数除法,向上取整)
  • 若k为奇数,则与上一行对应位置字符相同;若k为偶数,则是上一行对应位置字符的反转(0变1,1变0)

换个更直观的角度:每一行的右半部分是左半部分的完全反转,我们只需要不断缩小k所在的区间,判断是否需要反转即可。

优化后的代码

递归版本(逻辑清晰,适合理解)

public static int solve(int A, int B)
{
    // 终止条件:第1行只有字符0
    if (A == 1)
        return 0;
    // 计算当前行的中间位置(即上一行的长度)
    int mid = (int)Math.Pow(2, A - 2);
    if (B <= mid)
    {
        // B在左半区,直接取上一行对应位置的结果
        return solve(A - 1, B);
    }
    else
    {
        // B在右半区,取上一行对应位置结果的反转值
        return 1 - solve(A - 1, B - mid);
    }
}

迭代版本(避免递归栈开销,适合更大的A值)

public static int solve(int A, int B)
{
    int result = 0;
    int currentLength = (int)Math.Pow(2, A - 1);
    while (currentLength > 1)
    {
        currentLength /= 2;
        if (B > currentLength)
        {
            // 进入右半区,反转结果
            result = 1 - result;
            B -= currentLength;
        }
        // 左半区无需反转,继续缩小范围
    }
    return result;
}

内存优化原理

不管A取值多大,这两个方案都只需要记录当前的位置和反转状态,完全不需要生成任何字符串。内存占用仅为O(1)(迭代版)或O(A)的递归栈深度(A=30时栈深度极小),彻底解决内存溢出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:36:29