78
78
79
79
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为矩阵的行数。
80
80
81
- 实际上,我们也可以维护三个变量 $f$, $g$ 和 $fp$,分别表示前 $i$ 行的最小数字和、第 $i$ 行的第二小数字和以及第 $i$ 行的最小数字在第 $fp$ 列。这样我们就可以将时间复杂度降低到 $O(n^2)$,空间复杂度降低到 $O(1 )$。
81
+ 我们注意到,状态 $f[ i ] [ j ] $ 只与 $f [ i - 1 ] [ k ] $ 有关,因此我们可以使用滚动数组优化空间复杂度,将空间复杂度优化到 $O(n )$。
82
82
83
83
<!-- tabs:start -->
84
84
88
88
class Solution :
89
89
def minFallingPathSum (self , grid : List[List[int ]]) -> int :
90
90
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)
97
98
```
98
99
99
100
#### Java
@@ -102,24 +103,22 @@ class Solution:
102
103
class Solution {
103
104
public int minFallingPathSum (int [][] grid ) {
104
105
int n = grid. length;
105
- int [][] f = new int [n + 1 ] [n];
106
+ int [] f = new int [n];
106
107
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]);
113
115
}
114
116
}
115
- f [i][j] = grid[i - 1 ][j] + (x == inf ? 0 : x );
117
+ g [i] += (t == inf ? 0 : t );
116
118
}
119
+ f = g;
117
120
}
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();
123
122
}
124
123
}
125
124
```
@@ -131,21 +130,22 @@ class Solution {
131
130
public:
132
131
int minFallingPathSum(vector<vector<int >>& grid) {
133
132
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 ] );
143
142
}
144
143
}
145
- f [ i] [ j ] = grid [ i - 1 ] [ j ] + (x == inf ? 0 : x );
144
+ g [ i] += (t == inf ? 0 : t );
146
145
}
146
+ f = move(g);
147
147
}
148
- return * min_element(f [ n ] , f [ n ] + n );
148
+ return ranges::min(f );
149
149
}
150
150
};
151
151
```
@@ -154,149 +154,75 @@ public:
154
154
155
155
```go
156
156
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])
170
166
}
171
167
}
172
- if x = = inf {
173
- x = 0
168
+ if t ! = inf {
169
+ g[i] += t
174
170
}
175
- f[i][j] = v + x
176
171
}
172
+ f = g
177
173
}
178
- return slices.Min(f[n] )
174
+ return slices.Min(f)
179
175
}
180
176
```
181
177
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 ]);
233
191
}
234
192
}
235
- f = ff;
236
- g = gg;
237
- fp = ffp;
193
+ g [i ] += t === Infinity ? 0 : t ;
238
194
}
239
- return f ;
195
+ f . splice ( 0 , n , ... g ) ;
240
196
}
197
+ return Math .min (... f );
241
198
}
242
199
```
243
200
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
+ }
264
218
}
219
+ g [i ] += if t == inf { 0 } else { t };
265
220
}
266
- f = ff;
267
- g = gg;
268
- fp = ffp;
221
+ f = g ;
269
222
}
270
- return f;
271
- }
272
- };
273
- ```
274
-
275
- #### Go
276
223
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
+ }
300
226
}
301
227
```
302
228
0 commit comments