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

递归式动态规划最小路径和代码疑问:两种写法差异解析

最小路径和递归解法的错误原因分析

我在求解动态规划最小路径和问题时,自己写的递归解法逻辑看似正确却无法运行,代码如下:

class Solution {
    public int minPathSum(int[][] arr) {
        return f(arr.length-1, arr[0].length-1, arr);
    }

    public int f(int i, int j, int[][] arr) {
        if (i < 0 || j < 0) return Integer.MAX_VALUE;
        if (i == 0 && j == 0) return arr[0][0];
        int up = arr[i][j] + f(i-1, j, arr);
        int left = arr[i][j] + f(i, j-1, arr);
        return Math.min(up, left);
    }
}

而网上找到的递归解法可以正常运行:

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length-1;
        int n = grid[0].length-1;
        return find(grid, m, n);
    }

    public int find(int grid[][], int m, int n) {
        if (m < 0 || n < 0) return Integer.MAX_VALUE;
        if (m == 0 && n == 0) return grid[0][0];
        return grid[m][n] + Math.min(find(grid, m-1, n), find(grid, m, n-1));
    }
}

两者的核心差异在于加法操作的时机,下面具体分析:

错误根源:整数溢出

你的代码会对所有递归分支的结果执行加法,包括边界情况返回的Integer.MAX_VALUE。Java中int是有符号32位整数,当正数与Integer.MAX_VALUE相加时,会触发整数溢出,结果变成负数(比如2 + Integer.MAX_VALUE会等于Integer.MIN_VALUE +1,是一个负数)。

举个具体场景:当计算第一行(i=0)的某个位置(j>0)时,up = arr[0][j] + f(-1,j,arr),这里f(-1,j,arr)返回Integer.MAX_VALUE,相加后得到负数。后续Math.min(负数, left)会错误地选择这个负数,导致最终结果完全偏离正确值。

可行解法的正确逻辑

可行代码先通过Math.min筛选出有效的最小路径和,再与当前格子的值相加:

  • 当某个递归分支返回Integer.MAX_VALUE(比如越界情况),Math.min会直接忽略这个无效值,选择另一个有效的路径和(比如左方或上方的有效路径);
  • 只对筛选后的有效路径和执行加法,完全避免了溢出问题。

比如同样计算第一行的位置(0,j):
grid[0][j] + Math.min(find(-1,j), find(0,j-1)) → Math.min(Integer.MAX_VALUE, 有效路径和)会直接取有效路径和,再加当前值得到正确结果。

总结差异

  • 你的写法:先对所有递归结果(包括无效的MAX_VALUE)执行加法,触发溢出;
  • 可行写法:先筛选有效路径和,再执行加法,避免溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:20:08