题:最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
实现:
// 最小路径和
public static int minPathSum(int[][] arr){
if (arr.length == 0){ // 数组长度为0 最小路径为0
return 0;
}
int[][] dp = new int[arr.length][arr[0].length]; // 存放各个节点的最小路径
/**
* 输入:
* [1, 3, 1]
* [1, 5, 1]
* [4, 2, 1]
* dp:
* [1, 4, 5]
* [2, 7, 6]
* [6, 8, 7]
*/
dp[0][0] = arr[0][0]; // 初始化
for (int i = 1; i < dp[0].length; i++){ // 最上面的一行节点只能由左边计算而来 从下标1开始(下标0在上面初始化了)
dp[0][i] = dp[0][i-1] + arr[0][i]; // 最小路径为 左边节点的最小路径 + 自身元素
}
for (int i = 1; i < arr.length; i++){ // 遍历每一行
for (int j = 0; j < dp[i].length; j++){ // 遍历每一列
if (j == 0){ // j = 0 表示为最左边一列 最左边一列为上面一行的同一列元素的最小路径 + 自身元素
dp[i][j] = dp[i-1][j] + arr[i][j]; // 上面一行的同一列元素的最小路径 + 自身元素
}else if (dp[i-1][j] < dp[i][j-1]){ // 判断左边元素的路径小还是上面一行元素的路径小
dp[i][j] = dp[i-1][j] + arr[i][j]; // 上面一行比较小
}else {
dp[i][j] = dp[i][j-1] + arr[i][j]; // 下面一行比较小 要是两边相等随便赋值哪个都是一样的
}
}
}
return dp[dp.length-1][dp[dp.length-1].length-1]; // 输出dp右下角的元素
}