LC.P1289[下降路径最小和II]

方法一:动态规划

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int minFallingPathSum(int[][] grid) {
int n = grid.length;
int[][] f = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
f[i][j] = Integer.MAX_VALUE;
}
}
System.arraycopy(grid[0], 0, f[0], 0, n);
for (int i = 1; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
if (j != k) {
f[i][j] = Math.min(f[i][j], f[i - 1][k] + grid[i][j]);
}
}
}
}
int ans = Integer.MAX_VALUE;
for (int x : f[n - 1]) {
ans = Math.min(ans, x);
}
return ans;
}
}
  • 时间复杂度:$O(n^3)$
  • 空间复杂度:$O(n^2)$

方法二:滚动数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int minFallingPathSum(int[][] grid) {
// f: 前 i 行的最小数字和 s: 前 i 行的第二小数字和 idx: 第 i 行的最小数字的所在列号
int f = 0, s = 0, idx = -1;
for (int[] row : grid) {
int ff = Integer.MAX_VALUE, ss = Integer.MAX_VALUE, t = -1;
for (int j = 0; j < row.length; ++j) {
int sum = (j == idx ? s : f) + row[j];
if (sum < ff) {
ss = ff;
ff = sum;
t = j;
} else if (sum < ss){
ss = sum;
}
}
f = ff;
s = ss;
idx = t;
}
return f;
}
}
  • 时间复杂度:$O(n^2)$
  • 空间复杂度:$O(1)$