题目
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
原题链接
64.最小路径和
涉及知识点:动态规划
解题思路
这是一道典型的动态规划问题
首先,我们要判断题目所给的这个二维数组是不是空数组,如果是空数组,直接返回0。
接着,我们需要创建一个与原始数组规模一样的数组:dp[m][n]
,其中dp[i][j]
表示从(0,0)点到(i,j)的最短路径。显然dp[0][0] = grid[0][0]
。
进一步,列出状态转移方程:
- i=0 && j>0:dp[0][j]=dp[0][j-1]+grid[0][j]
- i>0 && j=0:dp[i][0]=dp[i-1][0]+grid[i][0]
- i>0 && j>0:dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1])+grid[i][j]
最后得到的dp[m-1][n-1]
就是题目要求的最小路径和
AC代码
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
if(grid == null || m == 0 || n == 0) return 0;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
//边界
for(int i=1; i<n; i++) {
dp[0][i] = dp[0][i-1]+grid[0][i];
}
for(int j=1; j<m; j++) {
dp[j][0] = dp[j-1][0]+grid[j][0];
}
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];
}
}