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

为何这段Java递归动态规划代码会抛出数组越界异常?

数组越界异常排查与大输入问题解决方案

一、数组越界异常的根本原因

Java数组采用0起始索引,长度为n的数组,有效索引范围是0到n-1。

看最初的代码:

  • count(int r, int c)里创建的dp数组是new int[r][c],比如调用count(3,3)时,dp的行、列有效索引都是0~2。
  • 但helper(r, c, dp)直接把传入的r、c当作数组索引使用,比如r=3、c=3时,会尝试访问dp[3][3],超出了数组的有效索引范围,直接触发ArrayIndexOutOfBoundsException。

更新后的代码里,小输入(比如(1,1)、(2,3))能正常运行,是因为这些输入的r、c值刚好在new int[4][4]数组的有效索引范围内(比如(2,3)对应索引2和3,4x4数组的列索引最大是3);但如果调用count(18,18, dp),18远大于数组的最大索引3,同样会触发越界异常。

二、大输入(如18,18)问题的解决方法

大输入的问题包含两个核心点:数组大小不匹配、整数类型溢出。

1. 保证DP数组的大小适配输入

你的代码逻辑是1起始索引(判断条件用r==1 || c==1),所以创建DP数组时,应该创建r+1行c+1列的数组,这样索引1r、1c都是有效的。比如处理(18,18)时,需要创建new int[19][19](或对应long/BigInteger类型的数组)。

2. 解决整数溢出问题

18x18网格的路径数是组合数C(34,17),结果为2333606220,这个值已经超过了Javaint类型的最大值(2^31-1=2147483647),用int存储会溢出得到错误的负数结果。需要改用更大的数值类型:

  • long类型:最大值为9223372036854775807,足够容纳(18,18)甚至(20,20)的路径数(C(38,19)=35345263800)。
  • BigInteger类型:支持任意精度的整数运算,能处理更大的输入(比如(30,30)的路径数)。

修复后的代码示例

long版本(适合中等大小输入)

public class Maze {
    public static long count(int r, int c, long[][] dp) {
        if (r == 1 || c == 1) {
            return dp[r][c] = 1;
        }
        if (dp[r][c] == 0) {
            dp[r][c] = count(r - 1, c, dp) + count(r, c - 1, dp);
        }
        return dp[r][c];
    }

    public static void main(String[] args) {
        int targetR = 18, targetC = 18;
        // 创建r+1行c+1列的数组,适配1起始索引逻辑
        long[][] dp = new long[targetR + 1][targetC + 1];
        System.out.println(count(targetR, targetC, dp)); // 输出2333606220
    }
}

BigInteger版本(适合超大输入)

import java.math.BigInteger;

public class Maze {
    public static BigInteger count(int r, int c, BigInteger[][] dp) {
        if (r == 1 || c == 1) {
            return dp[r][c] = BigInteger.ONE;
        }
        // BigInteger默认初始值为null,所以判断是否未初始化
        if (dp[r][c] == null) {
            dp[r][c] = count(r - 1, c, dp).add(count(r, c - 1, dp));
        }
        return dp[r][c];
    }

    public static void main(String[] args) {
        int targetR = 18, targetC = 18;
        BigInteger[][] dp = new BigInteger[targetR + 1][targetC + 1];
        System.out.println(count(targetR, targetC, dp)); // 输出2333606220

        // 处理更大的输入,比如30x30
        targetR = 30; targetC = 30;
        dp = new BigInteger[targetR + 1][targetC + 1];
        System.out.println(count(targetR, targetC, dp)); // 输出结果为C(58,29)的数值
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:55:17