Given a square array of integers A
, we want the minimum sum of a falling path through A
.
A falling path starts at any element in the first row, and chooses one element from each row. The next row’s choice must be in a column that is different from the previous row’s column by at most one.
Example 1:
Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: 12
Explanation:
The possible falling paths are:
- `[1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]`
- `[2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]`
- `[3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]`
The falling path with the smallest sum is [1,4,7]
, so the answer is 12
.
Note:
1 <= A.length == A[0].length <= 100
-100 <= A[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>>& A) {
if (A.size() == 1) return A[0][0];
int n = A.size(), res = INT_MAX;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < n; ++j) {
int pre = A[i - 1][j];
if (j > 0) pre = min(pre, A[i - 1][j - 1]);
if (j < n - 1) pre = min(pre, A[i - 1][j + 1]);
A[i][j] += pre;
if (i == n - 1) res = min(res, A[i][j]);
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/931
类似题目:
Minimum Falling Path Sum II
参考资料:
https://leetcode.com/problems/minimum-falling-path-sum/
https://leetcode.com/problems/minimum-falling-path-sum/discuss/186666/C%2B%2BJava-4-lines-DP
LeetCode All in One 题目讲解汇总(持续更新中…)
转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com