题目
931.
下降路径最小和
给你一个 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
标签
数组, 动态规划, 矩阵
题解
【下降路径最小和】动态规划
动态规划
不能想到,该问题具有无后效性,适合用动态规划,具体来说,第 \(i\) 行的结果只取决于第 \(i - 1\) 行而不用考虑第 \(i - 1\) 行之前的路径。
据此还可以使用滚动数组进行优化
1 2 3 4 5 6 7 8 9
| class Solution: def minFallingPathSum(self, matrix: List[List[int]]) -> int: n, m = len(matrix), len(matrix[0]) for i in range(1, n): for j in range(m): matrix[i][j] += min(matrix[i - 1][j], (matrix[i - 1][j - 1] if j > 0 else float('inf')), (matrix[i - 1][j + 1] if j + 1 < m else float('inf'))) return min(matrix[-1])
|
1 2 3 4 5 6 7 8 9 10
| class Solution: def minFallingPathSum(self, matrix: List[List[int]]) -> int: n, m = len(matrix), len(matrix[0]) dp = matrix[0] for i in range(1, n): dp = [min(dp[j], (dp[j - 1] if j > 0 else float('inf')), (dp[j + 1] if j + 1 < m else float('inf'))) + matrix[i][j] for j in range(m)] return min(dp)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int minFallingPathSum(int[][] matrix) { int n = matrix.length; int[][] dp = new int[n][n + 2]; for (int[] s : dp) Arrays.fill(s, 0x3f3f3f3f);
for (int i = 0; i < n; ++i) { dp[0][i + 1] = matrix[0][i]; }
for (int i = 1; i < n; ++i) { for (int j = 0; j < n; ++j) { dp[i][j + 1] = matrix[i][j] + Math.min(dp[i - 1][j], Math.min(dp[i - 1][j + 1], dp[i - 1][j + 2])); } }
int ans = dp[n - 1][0]; for (int s : dp[n - 1]) ans = Math.min(ans, s); return ans; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public: int minFallingPathSum(vector<vector<int>>& matrix) { int n = matrix.size(), m = matrix[0].size(); for (int i = 1; i < n; ++i) { for (int j = 0; j < m; ++j) { matrix[i][j] += min(matrix[i - 1][j], min(j > 0 ? matrix[i - 1][j - 1] : INT_MAX, j + 1 < m ? matrix[i - 1][j + 1] : INT_MAX)); } } int ans = INT_MAX; for (int i = 0; i < m; ++i) ans = min(ans, matrix[n - 1][i]); return ans; } };
|
- 时间复杂度: \(O(nm)\)
- 空间复杂度: \(O(1)\) -
原地修改,\(O(m)\) - 滚动数组,\(O(nm)\) - 无优化
如果对你有帮助的话,请给我点个赞吧~
欢迎前往 我的博客
或 Algorithm -
Github 查看更多题解