一、力扣64. 最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
1.找出DP状态
此题需要求出从左上角出发,到达坐标(m,n)的路径数字和最小值。因此不难想到,子问题就是从左上角出发,到达坐标(i,j)的路径数字和最小值。
令 f[i][j]表示从左上角到坐标(i,j)的路径数字和最小值,原问题即可被划分为多个求最优值的子问题,且由于每次只能向下或向右移动一步,因此 f[i][j]的取值由f[i-1][j]和f[i][j-1]的值决定。
进一步验证,可以发现, f[i][j] 的取值与f[i-1][j]和f[i][j-1]所对应的具体路径无关。
2.找出DP状态转移方程
确定完「DP 状态」后,继续确定「DP 转移方程」。
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
这里需要注意边界问题,比如第一行和第一列,只能向下或者向右运动。
3. 算法实现
// 利用动态规划
/**
* 从左上角出发,到达坐标(i,j)的路径数字和最小值。
* 令 f[i][j]表示从左上角到坐标(i,j)的路径数字和最小值,原问题即可被划分为多个求最优值的子问题,
* 且由于每次只能向下或向右移动一步,因此 f[i][j]的取值由f[i-1][j]和f[i][j-1]的值决定,即符合「最优子结构原则」。
* 进一步验证,可以发现, f[i][j] 的取值与f[i-1][j]和f[i][j-1]所对应的具体路径无关,因此符合「无后效性」。
* 则dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
* 这里需要注意边界问题,比如第一行和第一列,只能向下或者向右运动。
*
* @param grid
* @return
*/
public static int minPathSum(int[][] grid) {
// 判断数据是否为空
if(grid==null||grid.length==0||grid[0].length==0){
return 0;
}
// 行
int rows = grid.length;
// 列
int cols = grid[0].length