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

求解LeetCode k-th-symbol-in-grammar题出现Java堆内存溢出错误

问题原因分析
  • 内存溢出的核心原因是你选择了暴力生成完整第n行序列的实现思路:当n=30时,第n行的长度是2^(29) = 536870912个int元素,单个int占4字节,仅这个数组就需要占用约2GB内存,远远超过JVM默认的堆内存上限,自然会抛出OOM错误。
  • 额外的无效开销:你采用了递归生成整行的逻辑,过程中没有提前终止的判断,哪怕只需要第k个元素,也要生成完整的整行数组,做了大量无效计算。
解决方案

该题的核心规律是:第n行的前半段和第n-1行完全相同,后半段是第n-1行每一位取反的结果。我们不需要生成完整数组,只需要递归判断k的位置即可,时间复杂度O(n),空间占用极低。
优化后的递归实现代码如下:

public class kthGrammer {
    public static int kthGrammar(int n, int k) {
        // 边界条件:第一行只有1个元素0
        if (n == 1) {
            return 0;
        }
        // 第n行的一半长度
        int half = 1 << (n - 2);
        // k在前半段,和n-1行的k位置取值相同
        if (k <= half) {
            return kthGrammar(n - 1, k);
        }
        // k在后半段,是n-1行k-half位置的取值取反
        else {
            return 1 - kthGrammar(n - 1, k - half);
        }
    }

    public static void main(String[] args) {
        System.out.println("\nAnswer: " + kthGrammar(30, 434991989));
    }
}
  • 上述实现完全不需要申请大数组,n=30时仅需要30层递归调用,内存占用可以忽略不计,不会出现OOM问题。
  • 还可以进一步优化为迭代版本,完全消除递归栈空间占用:
public static int kthGrammar(int n, int k) {
    int res = 0;
    while (n > 1) {
        int half = 1 << (n - 2);
        if (k > half) {
            res = 1 - res;
            k -= half;
        }
        n--;
    }
    return res;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:54:00