传送门:https://leetcode-cn.com/problems/minimum-path-sum/

题目

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

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

示例 1:
**
[LeetCode]Dp64 最小路径和 - 图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

解题思路:动态规划 -> 滚动数组降维

创建二维数组 dp,与原始网格的大小相同,dp[i][j] 表示从(0,0)出发到 (i,j) 位置的最小路径和。显然,dp[0][0]=grid[0][0]
由于只能向下或者向右移动,导致 dp[i][j] 仅与 dp[i-1][j]dp[i][j-1] 有关

状态转移方程:

  1. - `j=0` 时,`dp[i][0]=dp[i-1][0]+grid[i][0]`
  2. - `i=0` 时,`dp[0][j]=dp[0][j-1]+grid[0][j]`
  3. - `i>0,j>0` 时,`dp[i][j]=Min(dp[i][j-1]+grid[i][j],dp[i-1][j]+grid[i][j])`

复杂度分析

时间复杂度:[LeetCode]Dp64 最小路径和 - 图2,其中 [LeetCode]Dp64 最小路径和 - 图3[LeetCode]Dp64 最小路径和 - 图4 分别是网格的行数和列数。
需要对整个网格遍历一次,计算 [LeetCode]Dp64 最小路径和 - 图5 的每个元素的值。
空间复杂度:[LeetCode]Dp64 最小路径和 - 图6,其中 [LeetCode]Dp64 最小路径和 - 图7[LeetCode]Dp64 最小路径和 - 图8 分别是网格的行数和列数。
创建一个二维数组 dpdp,和网格大小相同。

代码

我的代码

public class Demo {
    //动态规划,滚动数组降维优化
    public static int minPathSum_0(int[][] grid) {
        int []dp=new int[grid[0].length];
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if(j==0)
                    dp[j]=dp[j]+grid[i][j];
                else if(i==0)
                    dp[j]=dp[j-1]+grid[i][j];
                else
                    dp[j]=Math.min(dp[j]+grid[i][j],dp[j-1]+grid[i][j]);
            }
        }
        return dp[grid[0].length-1];
    }
    //动态规划,dp[i][j]代表从(0,0)到达(i,j)的最小总和
    //状态转移方程:dp[i][j]=Min(dp[i][j-1]+grid[i][j],dp[i-1][j]+grid[i][j]);
    public static int minPathSum_1(int[][] grid) {
        int[][]dp=new int[grid.length][grid[0].length];
        dp[0][0]=grid[0][0];
        //1.预处理0行数据
        for (int i = 1; i < grid[0].length; i++) {
            dp[0][i]=dp[0][i-1]+grid[0][i];
        }
        //2.预处理0列数据
        for (int i = 1; i < grid.length; i++) {
            dp[i][0]=dp[i-1][0]+grid[i][0];
        }
        //3.状态转移
        for (int i = 1; i < grid.length; i++) {
            for (int j = 1; j < grid[0].length; j++) {
                dp[i][j]=Math.min(dp[i][j-1]+grid[i][j],dp[i-1][j]+grid[i][j]);
            }
        }
        return dp[grid.length-1][grid[0].length-1];
    }
    public static void main(String[] args) {
        System.out.println(minPathSum_1(new int[][]{{1,2,3},{4,5,6}}));
    }
}