题目:
给你一个 n x n
的方形 整数数组 matrix
,请你找出并返回通过 matrix
的下降路径 的最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col)
的下一个元素应当是 (row + 1, col - 1)
、(row + 1, col)
或者 (row + 1, col + 1)
。
示例 1:

输入:matrix = [[2,1,3],[6,5,4],[7,8,9]] 输出:13 解释:如图所示,为和最小的两条下降路径
示例 2:

输入:matrix = [[-19,57],[-40,-5]] 输出:-59 解释:如图所示,为和最小的下降路径
提示:
n == matrix.length == matrix[i].length
1 <= n <= 100
-100 <= matrix[i][j] <= 100
解法:动态规划
cpp
class Solution {
public:
// void print(vector<vector<int>> ans) {
// int n = ans.size();
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < n; j++) {
// cout << ans[i][j] << " ";
// }
// cout << endl;
// }
// }
int minFallingPathSum(vector<vector<int>>& matrix) {
int n = matrix.size();
vector<vector<int>> ans(n, vector<int>(n, 0));
// 初始第一行
for (int i = 0; i < n; i++) {
ans[0][i] = matrix[0][i];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j == 0) {
ans[i][j] = min(matrix[i][j] + ans[i - 1][j],
matrix[i][j] + ans[i - 1][j + 1]);
} else if (j == n - 1) {
ans[i][j] = min(matrix[i][j] + ans[i - 1][j],
matrix[i][j] + ans[i - 1][j - 1]);
} else {
ans[i][j] = min(matrix[i][j] + ans[i-1][j+1], min(matrix[i][j] + ans[i-1][j], matrix[i][j] + ans[i-1][j-1]));
}
}
}
return *min_element(ans[n-1].begin(), ans[n-1].end());
}
};
代码解释
-
初始化:
-
n
是矩阵的大小。 -
ans
是一个n x n
的二维数组,用于存储从第一行到当前位置的最小路径和。
-
-
初始化第一行:
- 因为第一行的每个元素本身就是起点,所以
ans[0][i]
直接等于matrix[0][i]
。
- 因为第一行的每个元素本身就是起点,所以
-
动态规划填充
ans
数组:-
从第二行开始(
i = 1
),对于每一行的每个元素matrix[i][j]
,计算从上一行的三个可能位置(左上、正上、右上)到当前位置的最小路径和。 -
如果当前元素在第一列(
j == 0
),则只能从正上方或右上方移动过来。 -
如果当前元素在最后一列(
j == n - 1
),则只能从正上方或左上方移动过来。 -
否则,可以从左上方、正上方或右上方移动过来。
-
通过
min
函数选择这三个可能路径中的最小值,并加上当前元素的值,更新ans[i][j]
。
-
-
返回结果:
-
最终,
ans
数组的最后一行存储了从第一行到最后一行的所有可能路径的最小和。 -
使用
min_element
函数找到最后一行的最小值,并返回它。
-
复杂度分析
-
时间复杂度 :
O(n^2)
,因为需要遍历整个矩阵。 -
空间复杂度 :
O(n^2)
,因为需要存储ans
数组。