Java_动态规划_最小路径和

88 阅读2分钟

题目链接: leetcode.cn/problems/0i…

题目描述:

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明: 一个机器人每次只能向下或者向右移动一步。

示例 1:

输入: grid = [[1,3,1],[1,5,1],[4,2,1]] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入: grid = [[1,2,3],[4,5,6]] 输出: 12

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 100

题目解析

又是一题动态规划,题目和之前的差别不大。
创建 dp[i][j] 表示在 i、j 下标处的数字总和(步数)。
题目中描述只能往右、正下方走,那么来时方向就只能是左方、正上方。我们只要判断左方的 dp 和正上方的 dp 值谁

dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];

这题在创建 dp 表的时候我选择的是 int[][] dp = new int[m + 1][n + 1]; 预留空间,我们要将表格中的值初始化为不会影响我们结果的值,所以我们除了第一行的第二列和第一列的第二行不设置值(默认为 0)其他的所有值都设置为最大值。假设我们的 dp 表为 5 × 5,我们应该将表初始化如下图

为什么要 0?我们在起点的时候,如果我们将起点的正上方和左方初始化为任何值,都会影响我们的结果,他会判断哪个 dp 值最小,然后加到本身,而默认值为 0 的话就不会有影响。

代码

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m + 1][n + 1];
        //初始化dp表
        for (int i = 2; i <= n; i++) dp[0][i] = Integer.MAX_VALUE;
        for (int i = 2; i <= m; i++) dp[i][0] = Integer.MAX_VALUE;
        //开始填表
        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 - 1][j - 1];
            }
        }
        return dp[m][n];
    }
}