题目描述
给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径的最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释:下面是两条和最小的下降路径,用加粗标注:
[[2,1,3], [[2,1,3],
[6,5,4], [6,5,4],
[7,8,9]] [7,8,9]]
他们的路径是 1 -> 4 -> 8 或者 1 -> 5 -> 7
思路分析
我们通过题目可以知道我们求的是最小和,又是熟悉的最字,通常带有这种字眼的题目,都是使用动态规划进行解题。
那么按照动态规划的解题步骤,我们需要先找出状态,这里的状态很明显就是最小和。然后我们要做出选择,选择就是二维数组里面的每一个数字,最后我们要初始化,因为题目中提到下降路径可以从第一行中的任何元素开始,所以我们的 dp 数组的初始化就是第一行元素,然后我们只要每次都从下一行中找出最小的数字进行相加,就可以得到我们的结果。
举个栗子:
我们从 2 开始出发,每一次都找到下一行中的最小的数组,那么就可以找到从 2 出发能够得到的最小和。然后我们依次从 1 和 3 出发得到各自的最小和,最后比较所有的路径的最小和,最小的那个便是答案。
AC 代码
public int minFallingPathSum(int[][] matrix) {
int[] row1 = matrix[0];
int[][] dp = new int[matrix.length][matrix[0].length];
// 初始化
for(int i = 0; i < matrix[0].length; i++){
dp[0][i] = matrix[0][i];
}
// 从第一行开始得到每一条路径的最小和
for(int i = 1; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
if(j == 0) dp[i][j] = Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[i - 1][j + 1]);
else if(j == matrix[0].length - 1) dp[i][j] = Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[i - 1][j - 1]);
else dp[i][j] = Math.min(Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[ i - 1][j - 1]), matrix[i][j] + dp[i - 1][j + 1]);
}
}
int res = Integer.MAX_VALUE;
// 从所有最小和中得到最小的那个
for(int i = 0; i < dp[0].length; i++){
if(res > dp[dp[0].length - 1][i]){
res = dp[dp[0].length - 1][i];
}
}
return res;
}
总结
这就是一道基础的动态规划题目,只要按照动态规划的解题步骤即可得出答案。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情