
思路:
还是一样,先使用递归来接,无非是向右和向下,然后得到两种方式进行比较,代码如下:
 public int minPathSum(int[][] grid) {
        return calculate(grid, 0, 0);
    }
    private int calculate(int[][] grid, int i, int j) {
        int m = grid.length;
        int n = grid[0].length;
        // 到达右下角
        if (i == m - 1 && j == n - 1) {
            return grid[i][j];
        }
        // 向下移动
        int down = Integer.MAX_VALUE;
        if (i < m - 1) {
            down = calculate(grid, i + 1, j);
        }
        // 向右移动
        int right = Integer.MAX_VALUE;
        if (j < n - 1) {
            right = calculate(grid, i, j + 1);
        }
        // 返回当前位置的值加上从当前位置向下或向右走的最小值
        return grid[i][j] + Math.min(down, right);
    } 
然后依据此来改动态规划:
使用动态规划(DP)解决问题是处理此类网格路径问题的更有效方法。在这种情况下,我们会创建一个与原网格同样大小的 dp 数组,其中 dp[i][j] 表示从左上角到位置 (i, j) 的最小路径和。
动态规划的思路:
- 状态定义:定义 
dp[i][j]为从起点(0, 0)到点(i, j)的最小路径和。 - 初始化: 
  
dp[0][0]应初始化为grid[0][0],因为它是起始点。- 第一行和第一列的每个点都只能从它左边或上边的点到达,因此可以直接累加。
 
 - 状态转移方程: 
  
- 对于网格中的每个点 
(i, j),dp[i][j]可以从上方(i-1, j)或左方(i, j-1)到达,因此dp[i][j]应为grid[i][j] + min(dp[i-1][j], dp[i][j-1])。 
 - 对于网格中的每个点 
 - 计算顺序:从左到右,从上到下依次计算。
 
代码如下:
public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];
        // 初始化起点
        dp[0][0] = grid[0][0];
        // 初始化第一列
        for (int i = 1; i < m; i++) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        // 初始化第一行
        for (int j = 1; j < n; j++) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        // 填充剩余的dp表
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        // 返回右下角的值
        return dp[m - 1][n - 1];
    }
 
                


















