[LeetCode] 931. Minimum Falling Path Sum 下降路径最小和
Given an n x n
array of integers matrix
, return the minimum sum of any falling path through matrix
.
A falling path starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position (row, col)
will be (row + 1, col - 1)
, (row + 1, col)
, or (row + 1, col + 1)
.
Example 1:
Input: matrix = [[2,1,3],[6,5,4],[7,8,9]]
Output: 13
Explanation: There are two falling paths with a minimum sum as shown.
Example 2:
Input: matrix = [[-19,57],[-40,-5]]
Output: -59
Explanation: The falling path with a minimum sum is shown.
Constraints:
n == matrix.length == matrix[i].length
1 <= n <= 100
-100 <= matrix[i][j] <= 100
这道题给了一个长宽相等的二维数组,说是让找一个列路径,使得相邻两个位置的数的距离不超过1,可以通过观察题目中给的例子来理解题意。由于每个位置上的累加值是由上一行的三个位置中较小的那个决定的,所以这就是一道典型的动态规划 Dynamic Programming 的题,为了节省空间,直接用数组A本身当作 dp 数组,其中 A[i][j] 就表示最后一个位置在 (i, j) 的最小的下降路径,则最终只要在最后一行中找最小值就是所求。由于要看上一行的值,所以要从第二行开始遍历,那么首先判断一下数组是否只有一行,是的话直接返回那个唯一的数字即可。否则从第二行开始遍历,一定存在的是 A[i-1][j] 这个数字,而它周围的两个数字需要判断一下,存在的话才进行比较取较小值,将最终的最小值加到当前的 A[i][j] 上即可。为了避免重新开一个 for 循环,判断一下,若当前是最后一行,则更新结果 res,参见代码如下:
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& matrix) {
if (matrix.size() == 1) return matrix[0][0];
int n = matrix.size(), res = INT_MAX;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < n; ++j) {
int pre = matrix[i - 1][j];
if (j > 0) pre = min(pre, matrix[i - 1][j - 1]);
if (j < n - 1) pre = min(pre, matrix[i - 1][j + 1]);
matrix[i][j] += pre;
if (i == n - 1) res = min(res, matrix[i][j]);
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/931
类似题目:
参考资料:
https://leetcode.com/problems/minimum-falling-path-sum/
https://leetcode.com/problems/minimum-falling-path-sum/discuss/186666/C%2B%2BJava-4-lines-DP