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
8888class 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:
102103class 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 {
131130public:
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
156156func 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