Skip to content

Commit 6e344cb

Browse files
committed
feat: add solutions to lc problem: No.1289
No.1289.Minimum Falling Path Sum II
1 parent 30c5674 commit 6e344cb

File tree

7 files changed

+490
-46
lines changed

7 files changed

+490
-46
lines changed

solution/1200-1299/1289.Minimum Falling Path Sum II/README.md

Lines changed: 209 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,58 @@
4848

4949
<!-- 这里可写通用的实现逻辑 -->
5050

51+
**方法一:动态规划**
52+
53+
我们定义 $f[i][j]$ 表示前 $i$ 行,且最后一个数字在第 $j$ 列的最小数字和。那么状态转移方程为:
54+
55+
$$
56+
f[i][j] = \min_{k \neq j} f[i - 1][k] + grid[i - 1][j]
57+
$$
58+
59+
其中 $k$ 表示第 $i - 1$ 行的数字在第 $k$ 列,第 $i$ 行第 $j$ 列的数字为 $grid[i - 1][j]$。
60+
61+
最后答案为 $f[n]$ 中的最小值。
62+
63+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为矩阵的行数。
64+
65+
实际上,我们也可以维护三个变量 $f$, $g$ 和 $fp$,分别表示前 $i$ 行的最小数字和、第 $i$ 行的第二小数字和以及第 $i$ 行的最小数字在第 $fp$ 列。这样我们就可以将时间复杂度降低到 $O(n^2)$,空间复杂度降低到 $O(1)$。
66+
5167
<!-- tabs:start -->
5268

5369
### **Python3**
5470

5571
<!-- 这里可写当前语言的特殊实现逻辑 -->
5672

5773
```python
74+
class Solution:
75+
def minFallingPathSum(self, grid: List[List[int]]) -> int:
76+
n = len(grid)
77+
f = [[0] * n for _ in range(n + 1)]
78+
for i, row in enumerate(grid, 1):
79+
for j, v in enumerate(row):
80+
x = min((f[i - 1][k] for k in range(n) if k != j), default=0)
81+
f[i][j] = v + x
82+
return min(f[n])
83+
```
5884

85+
```python
86+
class Solution:
87+
def minFallingPathSum(self, grid: List[List[int]]) -> int:
88+
f = g = 0
89+
fp = -1
90+
for row in grid:
91+
ff = gg = inf
92+
ffp = -1
93+
for j, v in enumerate(row):
94+
s = (g if j == fp else f) + v
95+
if s < ff:
96+
gg = ff
97+
ff = s
98+
ffp = j
99+
elif s < gg:
100+
gg = s
101+
f, g, fp, = ff, gg, ffp
102+
return f
59103
```
60104

61105
### **Java**
@@ -64,25 +108,176 @@
64108

65109
```java
66110
class Solution {
67-
public void rotate(int[] nums, int k) {
68-
int[] res = new int[nums.length];
69-
int leftInit = 0;
70-
if (nums.length < k) {
71-
k = k % nums.length;
111+
public int minFallingPathSum(int[][] grid) {
112+
int n = grid.length;
113+
int[][] f = new int[n + 1][n];
114+
final int inf = 1 << 30;
115+
for (int i = 1; i <= n; ++i) {
116+
for (int j = 0; j < n; ++j) {
117+
int x = inf;
118+
for (int k = 0; k < n; ++k) {
119+
if (k != j) {
120+
x = Math.min(x, f[i - 1][k]);
121+
}
122+
}
123+
f[i][j] = grid[i - 1][j] + (x == inf ? 0 : x);
124+
}
72125
}
73-
for (int i = nums.length - k; i < nums.length; i++) {
74-
res[leftInit] = nums[i];
75-
leftInit++;
126+
int ans = inf;
127+
for (int x : f[n]) {
128+
ans = Math.min(ans, x);
76129
}
77-
int rightInit = 0;
78-
for (int i = k; i < nums.length; i++) {
79-
res[i] = nums[rightInit];
80-
rightInit++;
130+
return ans;
131+
}
132+
}
133+
```
134+
135+
```java
136+
class Solution {
137+
public int minFallingPathSum(int[][] grid) {
138+
int f = 0, g = 0;
139+
int fp = -1;
140+
final int inf = 1 << 30;
141+
for (int[] row : grid) {
142+
int ff = inf, gg = inf;
143+
int ffp = -1;
144+
for (int j = 0; j < row.length; ++j) {
145+
int s = (j != fp ? f : g) + row[j];
146+
if (s < ff) {
147+
gg = ff;
148+
ff = s;
149+
ffp = j;
150+
} else if (s < gg) {
151+
gg = s;
152+
}
153+
}
154+
f = ff;
155+
g = gg;
156+
fp = ffp;
157+
}
158+
return f;
159+
}
160+
}
161+
```
162+
163+
### **C++**
164+
165+
```cpp
166+
class Solution {
167+
public:
168+
int minFallingPathSum(vector<vector<int>>& grid) {
169+
int n = grid.size();
170+
int f[n + 1][n];
171+
memset(f, 0, sizeof(f));
172+
const int inf = 1 << 30;
173+
for (int i = 1; i <= n; ++i) {
174+
for (int j = 0; j < n; ++j) {
175+
int x = inf;
176+
for (int k = 0; k < n; ++k) {
177+
if (k != j) {
178+
x = min(x, f[i - 1][k]);
179+
}
180+
}
181+
f[i][j] = grid[i - 1][j] + (x == inf ? 0 : x);
182+
}
81183
}
82-
for (int i = 0; i < nums.length; i++) {
83-
nums[i] = res[i];
184+
return *min_element(f[n], f[n] + n);
185+
}
186+
};
187+
```
188+
189+
```cpp
190+
class Solution {
191+
public:
192+
int minFallingPathSum(vector<vector<int>>& grid) {
193+
int n = grid.size();
194+
int f = 0, g = 0, fp = -1;
195+
const int inf = 1 << 30;
196+
for (auto& row : grid) {
197+
int ff = inf, gg = inf;
198+
int ffp = -1;
199+
for (int j = 0; j < n; ++j) {
200+
int s = (fp != j ? f : g) + row[j];
201+
if (s < ff) {
202+
gg = ff;
203+
ff = s;
204+
ffp = j;
205+
} else if (s < gg) {
206+
gg = s;
207+
}
208+
}
209+
f = ff;
210+
g = gg;
211+
fp = ffp;
84212
}
213+
return f;
85214
}
215+
};
216+
```
217+
218+
### **Go**
219+
220+
```go
221+
func minFallingPathSum(grid [][]int) int {
222+
n := len(grid)
223+
f := make([][]int, n+1)
224+
for i := range f {
225+
f[i] = make([]int, n)
226+
}
227+
const inf = 1 << 30
228+
for i, row := range grid {
229+
i++
230+
for j, v := range row {
231+
x := inf
232+
for k := range row {
233+
if k != j {
234+
x = min(x, f[i-1][k])
235+
}
236+
}
237+
if x == inf {
238+
x = 0
239+
}
240+
f[i][j] = v + x
241+
}
242+
}
243+
ans := inf
244+
for _, x := range f[n] {
245+
ans = min(ans, x)
246+
}
247+
return ans
248+
}
249+
250+
func min(a, b int) int {
251+
if a < b {
252+
return a
253+
}
254+
return b
255+
}
256+
```
257+
258+
```go
259+
func minFallingPathSum(grid [][]int) int {
260+
const inf = 1 << 30
261+
f, g := 0, 0
262+
fp := -1
263+
for _, row := range grid {
264+
ff, gg := inf, inf
265+
ffp := -1
266+
for j, v := range row {
267+
s := f
268+
if j == fp {
269+
s = g
270+
}
271+
s += v
272+
if s < ff {
273+
ff, gg, ffp = s, ff, j
274+
} else if s < gg {
275+
gg = s
276+
}
277+
}
278+
f, g, fp = ff, gg, ffp
279+
}
280+
return f
86281
}
87282
```
88283

0 commit comments

Comments
 (0)