Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 250845d

Browse files
authored
feat: add solutions to lc problem: No.1289 (doocs#4072)
No.1289.Minimum Falling Path Sum II
1 parent c38da54 commit 250845d

File tree

12 files changed

+264
-452
lines changed

12 files changed

+264
-452
lines changed

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

Lines changed: 81 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ $$
7878

7979
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为矩阵的行数。
8080

81-
实际上,我们也可以维护三个变量 $f$, $g$ 和 $fp$,分别表示前 $i$ 行的最小数字和、第 $i$ 行的第二小数字和以及第 $i$ 行的最小数字在第 $fp$ 列。这样我们就可以将时间复杂度降低到 $O(n^2)$,空间复杂度降低到 $O(1)$。
81+
我们注意到,状态 $f[i][j]$ 只与 $f[i - 1][k]$ 有关,因此我们可以使用滚动数组优化空间复杂度,将空间复杂度优化到 $O(n)$。
8282

8383
<!-- tabs:start -->
8484

@@ -88,12 +88,13 @@ $$
8888
class Solution:
8989
def minFallingPathSum(self, grid: List[List[int]]) -> int:
9090
n = len(grid)
91-
f = [[0] * n for _ in range(n + 1)]
92-
for i, row in enumerate(grid, 1):
93-
for j, v in enumerate(row):
94-
x = min((f[i - 1][k] for k in range(n) if k != j), default=0)
95-
f[i][j] = v + x
96-
return min(f[n])
91+
f = [0] * n
92+
for row in grid:
93+
g = row[:]
94+
for i in range(n):
95+
g[i] += min((f[j] for j in range(n) if j != i), default=0)
96+
f = g
97+
return min(f)
9798
```
9899

99100
#### Java
@@ -102,24 +103,22 @@ class Solution:
102103
class Solution {
103104
public int minFallingPathSum(int[][] grid) {
104105
int n = grid.length;
105-
int[][] f = new int[n + 1][n];
106+
int[] f = new int[n];
106107
final int inf = 1 << 30;
107-
for (int i = 1; i <= n; ++i) {
108-
for (int j = 0; j < n; ++j) {
109-
int x = inf;
110-
for (int k = 0; k < n; ++k) {
111-
if (k != j) {
112-
x = Math.min(x, f[i - 1][k]);
108+
for (int[] row : grid) {
109+
int[] g = row.clone();
110+
for (int i = 0; i < n; ++i) {
111+
int t = inf;
112+
for (int j = 0; j < n; ++j) {
113+
if (j != i) {
114+
t = Math.min(t, f[j]);
113115
}
114116
}
115-
f[i][j] = grid[i - 1][j] + (x == inf ? 0 : x);
117+
g[i] += (t == inf ? 0 : t);
116118
}
119+
f = g;
117120
}
118-
int ans = inf;
119-
for (int x : f[n]) {
120-
ans = Math.min(ans, x);
121-
}
122-
return ans;
121+
return Arrays.stream(f).min().getAsInt();
123122
}
124123
}
125124
```
@@ -131,21 +130,22 @@ class Solution {
131130
public:
132131
int minFallingPathSum(vector<vector<int>>& grid) {
133132
int n = grid.size();
134-
int f[n + 1][n];
135-
memset(f, 0, sizeof(f));
136-
const int inf = 1 << 30;
137-
for (int i = 1; i <= n; ++i) {
138-
for (int j = 0; j < n; ++j) {
139-
int x = inf;
140-
for (int k = 0; k < n; ++k) {
141-
if (k != j) {
142-
x = min(x, f[i - 1][k]);
133+
vector<int> f(n);
134+
const int inf = 1e9;
135+
for (const auto& row : grid) {
136+
vector<int> g = row;
137+
for (int i = 0; i < n; ++i) {
138+
int t = inf;
139+
for (int j = 0; j < n; ++j) {
140+
if (j != i) {
141+
t = min(t, f[j]);
143142
}
144143
}
145-
f[i][j] = grid[i - 1][j] + (x == inf ? 0 : x);
144+
g[i] += (t == inf ? 0 : t);
146145
}
146+
f = move(g);
147147
}
148-
return *min_element(f[n], f[n] + n);
148+
return ranges::min(f);
149149
}
150150
};
151151
```
@@ -154,149 +154,75 @@ public:
154154
155155
```go
156156
func minFallingPathSum(grid [][]int) int {
157-
n := len(grid)
158-
f := make([][]int, n+1)
159-
for i := range f {
160-
f[i] = make([]int, n)
161-
}
162-
const inf = 1 << 30
163-
for i, row := range grid {
164-
i++
165-
for j, v := range row {
166-
x := inf
167-
for k := range row {
168-
if k != j {
169-
x = min(x, f[i-1][k])
157+
f := make([]int, len(grid))
158+
const inf = math.MaxInt32
159+
for _, row := range grid {
160+
g := slices.Clone(row)
161+
for i := range f {
162+
t := inf
163+
for j := range row {
164+
if j != i {
165+
t = min(t, f[j])
170166
}
171167
}
172-
if x == inf {
173-
x = 0
168+
if t != inf {
169+
g[i] += t
174170
}
175-
f[i][j] = v + x
176171
}
172+
f = g
177173
}
178-
return slices.Min(f[n])
174+
return slices.Min(f)
179175
}
180176
```
181177

182-
<!-- tabs:end -->
183-
184-
<!-- solution:end -->
185-
186-
<!-- solution:start -->
187-
188-
### 方法二
189-
190-
<!-- tabs:start -->
191-
192-
#### Python3
193-
194-
```python
195-
class Solution:
196-
def minFallingPathSum(self, grid: List[List[int]]) -> int:
197-
f = g = 0
198-
fp = -1
199-
for row in grid:
200-
ff = gg = inf
201-
ffp = -1
202-
for j, v in enumerate(row):
203-
s = (g if j == fp else f) + v
204-
if s < ff:
205-
gg = ff
206-
ff = s
207-
ffp = j
208-
elif s < gg:
209-
gg = s
210-
f, g, fp = ff, gg, ffp
211-
return f
212-
```
213-
214-
#### Java
215-
216-
```java
217-
class Solution {
218-
public int minFallingPathSum(int[][] grid) {
219-
int f = 0, g = 0;
220-
int fp = -1;
221-
final int inf = 1 << 30;
222-
for (int[] row : grid) {
223-
int ff = inf, gg = inf;
224-
int ffp = -1;
225-
for (int j = 0; j < row.length; ++j) {
226-
int s = (j != fp ? f : g) + row[j];
227-
if (s < ff) {
228-
gg = ff;
229-
ff = s;
230-
ffp = j;
231-
} else if (s < gg) {
232-
gg = s;
178+
#### TypeScript
179+
180+
```ts
181+
function minFallingPathSum(grid: number[][]): number {
182+
const n = grid.length;
183+
const f: number[] = Array(n).fill(0);
184+
for (const row of grid) {
185+
const g = [...row];
186+
for (let i = 0; i < n; ++i) {
187+
let t = Infinity;
188+
for (let j = 0; j < n; ++j) {
189+
if (j !== i) {
190+
t = Math.min(t, f[j]);
233191
}
234192
}
235-
f = ff;
236-
g = gg;
237-
fp = ffp;
193+
g[i] += t === Infinity ? 0 : t;
238194
}
239-
return f;
195+
f.splice(0, n, ...g);
240196
}
197+
return Math.min(...f);
241198
}
242199
```
243200

244-
#### C++
245-
246-
```cpp
247-
class Solution {
248-
public:
249-
int minFallingPathSum(vector<vector<int>>& grid) {
250-
int n = grid.size();
251-
int f = 0, g = 0, fp = -1;
252-
const int inf = 1 << 30;
253-
for (auto& row : grid) {
254-
int ff = inf, gg = inf;
255-
int ffp = -1;
256-
for (int j = 0; j < n; ++j) {
257-
int s = (fp != j ? f : g) + row[j];
258-
if (s < ff) {
259-
gg = ff;
260-
ff = s;
261-
ffp = j;
262-
} else if (s < gg) {
263-
gg = s;
201+
#### Rust
202+
203+
```rust
204+
impl Solution {
205+
pub fn min_falling_path_sum(grid: Vec<Vec<i32>>) -> i32 {
206+
let n = grid.len();
207+
let mut f = vec![0; n];
208+
let inf = i32::MAX;
209+
210+
for row in grid {
211+
let mut g = row.clone();
212+
for i in 0..n {
213+
let mut t = inf;
214+
for j in 0..n {
215+
if j != i {
216+
t = t.min(f[j]);
217+
}
264218
}
219+
g[i] += if t == inf { 0 } else { t };
265220
}
266-
f = ff;
267-
g = gg;
268-
fp = ffp;
221+
f = g;
269222
}
270-
return f;
271-
}
272-
};
273-
```
274-
275-
#### Go
276223

277-
```go
278-
func minFallingPathSum(grid [][]int) int {
279-
const inf = 1 << 30
280-
f, g := 0, 0
281-
fp := -1
282-
for _, row := range grid {
283-
ff, gg := inf, inf
284-
ffp := -1
285-
for j, v := range row {
286-
s := f
287-
if j == fp {
288-
s = g
289-
}
290-
s += v
291-
if s < ff {
292-
ff, gg, ffp = s, ff, j
293-
} else if s < gg {
294-
gg = s
295-
}
296-
}
297-
f, g, fp = ff, gg, ffp
298-
}
299-
return f
224+
*f.iter().min().unwrap()
225+
}
300226
}
301227
```
302228

0 commit comments

Comments
 (0)