51
51
52
52
** 方法一:记忆化搜索**
53
53
54
- 时间复杂度 $O(mn)$。
54
+ 我们设计一个函数 $dfs(i, j)$,它表示从矩阵中的坐标 $(i, j)$ 出发,可以得到的最长递增路径的长度。那么答案就是 $\max_ {i, j} \textit{dfs}(i, j)$。
55
+
56
+ 函数 $dfs(i, j)$ 的执行逻辑如下:
57
+
58
+ - 如果 $(i, j)$ 已经被访问过,直接返回 $\textit{f}(i, j)$;
59
+ - 否则对 $(i, j)$ 进行搜索,搜索四个方向的坐标 $(x, y)$,如果满足 $0 \le x < m, 0 \le y < n$ 以及 $matrix[ x] [ y ] \gt matrix[ i] [ j ] $,那么对 $(x, y)$ 进行搜索。搜索结束后,将 $\textit{f}(i, j)$ 更新为 $\textit{f}(i, j) = \max(\textit{f}(i, j), \textit{f}(x, y) + 1)$。最后返回 $\textit{f}(i, j)$。
60
+
61
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
55
62
56
63
相似题目:[ 2328. 网格图中递增路径的数目] ( /solution/2300-2399/2328.Number%20of%20Increasing%20Paths%20in%20a%20Grid/README.md ) 。
57
64
65
72
class Solution :
66
73
def longestIncreasingPath (self , matrix : List[List[int ]]) -> int :
67
74
@cache
68
- def dfs (i , j ) :
69
- ans = 1
70
- for a, b in [[ - 1 , 0 ], [ 1 , 0 ], [ 0 , 1 ], [ 0 , - 1 ]] :
75
+ def dfs (i : int , j : int ) -> int :
76
+ ans = 0
77
+ for a, b in pairwise(( - 1 , 0 , 1 , 0 , - 1 )) :
71
78
x, y = i + a, j + b
72
79
if 0 <= x < m and 0 <= y < n and matrix[x][y] > matrix[i][j]:
73
- ans = max (ans, dfs(x, y) + 1 )
74
- return ans
80
+ ans = max (ans, dfs(x, y))
81
+ return ans + 1
75
82
76
83
m, n = len (matrix), len (matrix[0 ])
77
84
return max (dfs(i, j) for i in range (m) for j in range (n))
@@ -83,42 +90,38 @@ class Solution:
83
90
84
91
``` java
85
92
class Solution {
86
- private int [][] memo;
87
- private int [][] matrix;
88
93
private int m;
89
94
private int n;
95
+ private int [][] matrix;
96
+ private int [][] f;
90
97
91
98
public int longestIncreasingPath (int [][] matrix ) {
92
- this . matrix = matrix;
93
99
m = matrix. length;
94
100
n = matrix[0 ]. length;
95
- memo = new int [m][n];
96
- for (int i = 0 ; i < m; ++ i) {
97
- Arrays . fill(memo[i], - 1 );
98
- }
101
+ f = new int [m][n];
102
+ this . matrix = matrix;
99
103
int ans = 0 ;
100
104
for (int i = 0 ; i < m; ++ i) {
101
- for (int j = 0 ; j < n; ++ j) {
105
+ for (int j = 0 ;j < n; ++ j) {
102
106
ans = Math . max(ans, dfs(i, j));
103
107
}
104
108
}
105
109
return ans;
106
110
}
107
111
108
112
private int dfs (int i , int j ) {
109
- if (memo [i][j] != - 1 ) {
110
- return memo [i][j];
113
+ if (f [i][j] != 0 ) {
114
+ return f [i][j];
111
115
}
112
- int ans = 1 ;
113
116
int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
114
117
for (int k = 0 ; k < 4 ; ++ k) {
115
- int x = i + dirs[k], y = j + dirs[k + 1 ];
118
+ int x = i + dirs[k];
119
+ int y = j + dirs[k + 1 ];
116
120
if (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]) {
117
- ans = Math . max(ans , dfs(x, y) + 1 );
121
+ f[i][j] = Math . max(f[i][j] , dfs(x, y));
118
122
}
119
123
}
120
- memo[i][j] = ans;
121
- return ans;
124
+ return ++ f[i][j];
122
125
}
123
126
}
124
127
```
@@ -128,33 +131,31 @@ class Solution {
128
131
``` cpp
129
132
class Solution {
130
133
public:
131
- vector<vector<int >> memo;
132
- vector<vector<int >> matrix;
133
- int m;
134
- int n;
135
-
136
134
int longestIncreasingPath(vector<vector<int >>& matrix) {
137
- m = matrix.size();
138
- n = matrix[0].size();
139
- memo.resize(m, vector<int>(n, -1));
140
- this->matrix = matrix;
135
+ int m = matrix.size(), n = matrix[ 0] .size();
136
+ int f[ m] [ n ] ;
137
+ memset(f, 0, sizeof(f));
141
138
int ans = 0;
142
- for (int i = 0; i < m; ++i)
143
- for (int j = 0; j < n; ++j)
144
- ans = max(ans, dfs(i, j));
145
- return ans;
146
- }
139
+ int dirs[ 5] = {-1, 0, 1, 0, -1};
147
140
148
- int dfs (int i, int j) {
149
- if (memo[ i] [ j ] != -1) return memo[ i] [ j ] ;
150
- int ans = 1;
151
- vector<int > dirs = {-1, 0, 1, 0, -1};
152
- for (int k = 0; k < 4; ++k) {
153
- int x = i + dirs[ k] , y = j + dirs[ k + 1] ;
154
- if (x >= 0 && x < m && y >= 0 && y < n && matrix[ x] [ y ] > matrix[ i] [ j ] )
155
- ans = max(ans, dfs(x, y) + 1);
141
+ function<int(int, int)> dfs = [&](int i, int j) -> int {
142
+ if (f[i][j]) {
143
+ return f[i][j];
144
+ }
145
+ for (int k = 0 ; k < 4 ; ++k) {
146
+ int x = i + dirs[k], y = j + dirs[k + 1];
147
+ if (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]) {
148
+ f[i][j] = max(f[i][j], dfs(x, y));
149
+ }
150
+ }
151
+ return ++f[i][j];
152
+ };
153
+
154
+ for (int i = 0; i < m; ++i) {
155
+ for (int j = 0; j < n; ++j) {
156
+ ans = max(ans, dfs(i, j));
157
+ }
156
158
}
157
- memo[ i] [ j ] = ans;
158
159
return ans;
159
160
}
160
161
};
@@ -163,38 +164,33 @@ public:
163
164
### ** Go**
164
165
165
166
``` go
166
- func longestIncreasingPath(matrix [][]int) int {
167
+ func longestIncreasingPath (matrix [][]int ) ( ans int ) {
167
168
m , n := len (matrix), len (matrix[0 ])
168
- memo := make([][]int, m)
169
- for i := range memo {
170
- memo[i] = make([]int, n)
171
- for j := range memo[i] {
172
- memo[i][j] = -1
173
- }
169
+ f := make ([][]int , m)
170
+ for i := range f {
171
+ f[i] = make ([]int , n)
174
172
}
175
- ans := -1
173
+ dirs := [ 5 ] int {- 1 , 0 , 1 , 0 , - 1 }
176
174
var dfs func (i, j int ) int
177
175
dfs = func (i, j int ) int {
178
- if memo [i][j] != -1 {
179
- return memo [i][j]
176
+ if f [i][j] != 0 {
177
+ return f [i][j]
180
178
}
181
- ans := 1
182
- dirs := []int{-1, 0, 1, 0, -1}
183
- for k := 0; k < 4; k++ {
184
- x, y := i+dirs[k], j+dirs[k+1]
185
- if x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j] {
186
- ans = max(ans, dfs(x, y)+1)
179
+ for k := 0 ; k < 4 ; k++ {
180
+ x , y := i+dirs[k], j+dirs[k+1 ]
181
+ if 0 <= x && x < m && 0 <= y && y < n && matrix[x][y] > matrix[i][j] {
182
+ f[i][j] = max (f[i][j], dfs (x, y))
187
183
}
188
184
}
189
- memo [i][j] = ans
190
- return ans
185
+ f [i][j]++
186
+ return f[i][j]
191
187
}
192
188
for i := 0 ; i < m; i++ {
193
189
for j := 0 ; j < n; j++ {
194
190
ans = max (ans, dfs (i, j))
195
191
}
196
192
}
197
- return ans
193
+ return
198
194
}
199
195
200
196
func max (a , b int ) int {
@@ -205,6 +201,45 @@ func max(a, b int) int {
205
201
}
206
202
```
207
203
204
+ ### ** TypeScript**
205
+
206
+ ``` ts
207
+ function longestIncreasingPath(matrix : number [][]): number {
208
+ const m = matrix .length ;
209
+ const n = matrix [0 ].length ;
210
+ const f: number [][] = Array (m )
211
+ .fill (0 )
212
+ .map (() => Array (n ).fill (0 ));
213
+ const dirs = [- 1 , 0 , 1 , 0 , - 1 ];
214
+ const dfs = (i : number , j : number ): number => {
215
+ if (f [i ][j ] > 0 ) {
216
+ return f [i ][j ];
217
+ }
218
+ for (let k = 0 ; k < 4 ; ++ k ) {
219
+ const x = i + dirs [k ];
220
+ const y = j + dirs [k + 1 ];
221
+ if (
222
+ x >= 0 &&
223
+ x < m &&
224
+ y >= 0 &&
225
+ y < n &&
226
+ matrix [x ][y ] > matrix [i ][j ]
227
+ ) {
228
+ f [i ][j ] = Math .max (f [i ][j ], dfs (x , y ));
229
+ }
230
+ }
231
+ return ++ f [i ][j ];
232
+ };
233
+ let ans = 0 ;
234
+ for (let i = 0 ; i < m ; ++ i ) {
235
+ for (let j = 0 ; j < n ; ++ j ) {
236
+ ans = Math .max (ans , dfs (i , j ));
237
+ }
238
+ }
239
+ return ans ;
240
+ }
241
+ ```
242
+
208
243
### ** ...**
209
244
210
245
```
0 commit comments