Problem: 931. 下降路径最小和
解题方法
d p [ i ] [ j ] dp[i][j] dp[i][j] 表示下降到第 i i i行第 j j j列的最小和。
因此,只存在三种转移
左上角: d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + m a t r i x [ i ] [ j ] dp[i][j]=dp[i-1][j-1] + matrix[i][j] dp[i][j]=dp[i−1][j−1]+matrix[i][j]
正上方: d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + m a t r i x [ i ] [ j ] dp[i][j]=dp[i-1][j] + matrix[i][j] dp[i][j]=dp[i−1][j]+matrix[i][j]
右上角: d p [ i ] [ j ] = d p [ i − 1 ] [ j + 1 ] + m a t r i x [ i ] [ j ] dp[i][j]=dp[i-1][j+1] + matrix[i][j] dp[i][j]=dp[i−1][j+1]+matrix[i][j]
取其中最小值即可
复杂度
-
时间复杂度: O ( n 2 ) O(n^2) O(n2)
-
空间复杂度: O ( n 2 ) O(n^2) O(n2)
Code
Python
class Solution:
def minFallingPathSum(self, matrix: List[List[int]]) -> int:
# 动态规划
# dp[i][j] 表示下降到第i行第j列的最小和
n = len(matrix)
dp = [[math.inf] * n for _ in range(n)]
for i in range(n):
# i 表示行
if i == 0:
for j in range(n):
dp[i][j] = matrix[i][j]
else:
# 三个转移
# 左上角的转移,正上方的转移,和右上角的转移
# 取最小值
for j in range(n):
if j == 0:
dp[i][j] = matrix[i][j] + min(dp[i - 1][j], dp[i - 1][j + 1])
elif j == n - 1:
dp[i][j] = matrix[i][j] + min(dp[i - 1][j - 1], dp[i - 1][j])
else:
dp[i][j]= matrix[i][j] + min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1])
return min(dp[n - 1])
Java
class Solution {
public int minFallingPathSum(int[][] matrix) {
// 创建dp数组
// dp[i][j] 表示下降到第i行第j列时的最小和
int n = matrix[0].length;
int[][] dp = new int[n][n];
for(int i = 0; i < n; i++){
if(i == 0){
for(int j = 0; j < n; j++){
dp[i][j] = matrix[i][j];
}
}
else{
for(int j = 0; j < n; j++){
dp[i][j] = dp[i - 1][j] + matrix[i][j];
if(j > 0){
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1] + matrix[i][j]);
}
if(j < n - 1){
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j + 1] + matrix[i][j]);
}
}
}
}
int ans = dp[n - 1][0];
for(int i = 0; i < n; i++){
ans = Math.min(ans, dp[n - 1][i]);
}
return ans;
}
}