@@ -114,65 +114,203 @@ tags:
114
114
115
115
<!-- solution:start -->
116
116
117
- ### 方法一
117
+ ### 方法一:记忆化搜索
118
118
119
- <!-- tabs:start -->
119
+ 我们设计一个函数 $\text{dfs}(i, j, k, \textit{cnt})$,表示上一个位置为 $(i, j)$,当前方向为 $k$,剩余可转向次数为 $\textit{cnt}$ 时,返回最长的 V 形对角线段长度。
120
120
121
- #### Python3
121
+ 函数 $\text{dfs}$ 的执行逻辑如下:
122
122
123
- ``` python
124
- class Solution :
125
- def lenOfVDiagonal (self , grid : List[List[int ]]) -> int :
126
- m, n = len (grid), len (grid[0 ])
127
- next_digit = {1 : 2 , 2 : 0 , 0 : 2 }
123
+ 我们首先基于上一个位置以及当前的方向,计算当前得到当前位置 $(x, y)$,然后计算当前目标值 $\textit{target}$。如果 $x$ 或 $y$ 不在矩阵范围内,或者 $\textit{grid}[ x] [ y ] \neq \textit{target}$,返回 $0$。
128
124
129
- def within_bounds (i , j ):
130
- return 0 <= i < m and 0 <= j < n
125
+ 否则,我们有两种选择:
131
126
132
- @cache
133
- def f (i , j , di , dj , turned ):
134
- result = 1
135
- successor = next_digit[grid[i][j]]
127
+ 1 . 继续沿着当前方向前进。
128
+ 2 . 在当前位置进行顺时针 90 度转向,然后继续前进。
129
+
130
+ 我们可以通过改变方向来实现顺时针 90 度转向。具体来说,如果当前方向为 $k$,则顺时针 90 度转向后的新方向为 $(k + 1) \bmod 4$。最后,我们选择这两种选择中的最大值作为当前状态的结果。
131
+
132
+ 在主函数中,我们遍历整个矩阵,对于每个值为 1 的位置,尝试四个方向的搜索,并更新答案。
133
+
134
+ 遍历结束后,返回答案即可。
136
135
137
- if within_bounds(i + di, j + dj) and grid[i + di][j + dj] == successor:
138
- result = 1 + f(i + di, j + dj, di, dj, turned)
136
+ 为了避免重复计算,我们使用记忆化搜索来缓存中间结果。
139
137
140
- if not turned:
141
- di, dj = dj, - di
142
- if within_bounds(i + di, j + dj) and grid[i + di][j + dj] == successor:
143
- result = max (result, 1 + f(i + di, j + dj, di, dj, True ))
138
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
144
139
145
- return result
140
+ <!-- tabs:start -->
146
141
147
- directions = ((1 , 1 ), (- 1 , 1 ), (1 , - 1 ), (- 1 , - 1 ))
148
- result = 0
142
+ #### Python3
149
143
150
- for i in range (m):
151
- for j in range (n):
152
- if grid[i][j] != 1 :
153
- continue
154
- for di, dj in directions:
155
- result = max (result, f(i, j, di, dj, False ))
144
+ ``` python
145
+ class Solution :
146
+ def lenOfVDiagonal (self , grid : List[List[int ]]) -> int :
147
+ @cache
148
+ def dfs (i : int , j : int , k : int , cnt : int ) -> int :
149
+ x, y = i + dirs[k], j + dirs[k + 1 ]
150
+ target = 2 if grid[i][j] == 1 else (2 - grid[i][j])
151
+ if not 0 <= x < m or not 0 <= y < n or grid[x][y] != target:
152
+ return 0
153
+ res = dfs(x, y, k, cnt)
154
+ if cnt > 0 :
155
+ res = max (res, dfs(x, y, (k + 1 ) % 4 , 0 ))
156
+ return 1 + res
156
157
157
- return result
158
+ m, n = len (grid), len (grid[0 ])
159
+ dirs = (1 , 1 , - 1 , - 1 , 1 )
160
+ ans = 0
161
+ for i, row in enumerate (grid):
162
+ for j, x in enumerate (row):
163
+ if x == 1 :
164
+ for k in range (4 ):
165
+ ans = max (ans, dfs(i, j, k, 1 ) + 1 )
166
+ return ans
158
167
```
159
168
160
169
#### Java
161
170
162
171
``` java
163
-
172
+ class Solution {
173
+ private int m, n;
174
+ private final int [] dirs = {1 , 1 , - 1 , - 1 , 1 };
175
+ private Integer [][][][] f;
176
+
177
+ public int lenOfVDiagonal (int [][] grid ) {
178
+ m = grid. length;
179
+ n = grid[0 ]. length;
180
+ f = new Integer [m][n][4 ][2 ];
181
+ int ans = 0 ;
182
+ for (int i = 0 ; i < m; i++ ) {
183
+ for (int j = 0 ; j < n; j++ ) {
184
+ if (grid[i][j] == 1 ) {
185
+ for (int k = 0 ; k < 4 ; k++ ) {
186
+ ans = Math . max(ans, dfs(grid, i, j, k, 1 ) + 1 );
187
+ }
188
+ }
189
+ }
190
+ }
191
+ return ans;
192
+ }
193
+
194
+ private int dfs (int [][] grid , int i , int j , int k , int cnt ) {
195
+ if (f[i][j][k][cnt] != null ) {
196
+ return f[i][j][k][cnt];
197
+ }
198
+ int x = i + dirs[k];
199
+ int y = j + dirs[k + 1 ];
200
+ int target = grid[i][j] == 1 ? 2 : (2 - grid[i][j]);
201
+ if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] != target) {
202
+ f[i][j][k][cnt] = 0 ;
203
+ return 0 ;
204
+ }
205
+ int res = dfs(grid, x, y, k, cnt);
206
+ if (cnt > 0 ) {
207
+ res = Math . max(res, dfs(grid, x, y, (k + 1 ) % 4 , 0 ));
208
+ }
209
+ f[i][j][k][cnt] = 1 + res;
210
+ return 1 + res;
211
+ }
212
+ }
164
213
```
165
214
166
215
#### C++
167
216
168
217
``` cpp
169
-
218
+ class Solution {
219
+ public:
220
+ static constexpr int MAXN = 501;
221
+ int f[ MAXN] [ MAXN ] [ 4] [ 2 ] ;
222
+
223
+ int lenOfVDiagonal(vector<vector<int>>& grid) {
224
+ int m = grid.size(), n = grid[0].size();
225
+ int dirs[5] = {1, 1, -1, -1, 1};
226
+ memset(f, -1, sizeof(f));
227
+
228
+ auto dfs = [&](this auto&& dfs, int i, int j, int k, int cnt) -> int {
229
+ if (f[i][j][k][cnt] != -1) {
230
+ return f[i][j][k][cnt];
231
+ }
232
+ int x = i + dirs[k];
233
+ int y = j + dirs[k + 1 ];
234
+ int target = grid[i][j] == 1 ? 2 : (2 - grid[i][j]);
235
+ if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] != target) {
236
+ f[i][j][k][cnt] = 0;
237
+ return 0;
238
+ }
239
+ int res = dfs(x, y, k, cnt);
240
+ if (cnt > 0) {
241
+ res = max(res, dfs(x, y, (k + 1) % 4, 0));
242
+ }
243
+ f[i][j][k][cnt] = 1 + res;
244
+ return 1 + res;
245
+ };
246
+
247
+ int ans = 0;
248
+ for (int i = 0; i < m; ++i) {
249
+ for (int j = 0; j < n; ++j) {
250
+ if (grid[i][j] == 1) {
251
+ for (int k = 0; k < 4; ++k) {
252
+ ans = max(ans, dfs(i, j, k, 1) + 1);
253
+ }
254
+ }
255
+ }
256
+ }
257
+ return ans;
258
+ }
259
+ };
170
260
```
171
261
172
262
#### Go
173
263
174
264
``` go
175
-
265
+ func lenOfVDiagonal (grid [][]int ) int {
266
+ m , n := len (grid), len (grid[0 ])
267
+ dirs := []int {1 , 1 , -1 , -1 , 1 }
268
+ f := make ([][][4 ][2 ]int , m)
269
+ for i := range f {
270
+ f[i] = make ([][4 ][2 ]int , n)
271
+ }
272
+
273
+ var dfs func (i, j, k, cnt int ) int
274
+ dfs = func (i, j, k, cnt int ) int {
275
+ if f[i][j][k][cnt] != 0 {
276
+ return f[i][j][k][cnt]
277
+ }
278
+
279
+ x := i + dirs[k]
280
+ y := j + dirs[k+1 ]
281
+
282
+ var target int
283
+ if grid[i][j] == 1 {
284
+ target = 2
285
+ } else {
286
+ target = 2 - grid[i][j]
287
+ }
288
+
289
+ if x < 0 || x >= m || y < 0 || y >= n || grid[x][y] != target {
290
+ f[i][j][k][cnt] = 0
291
+ return 0
292
+ }
293
+
294
+ res := dfs (x, y, k, cnt)
295
+ if cnt > 0 {
296
+ res = max (res, dfs (x, y, (k+1 )%4 , 0 ))
297
+ }
298
+ f[i][j][k][cnt] = res + 1
299
+ return res + 1
300
+ }
301
+
302
+ ans := 0
303
+ for i := 0 ; i < m; i++ {
304
+ for j := 0 ; j < n; j++ {
305
+ if grid[i][j] == 1 {
306
+ for k := 0 ; k < 4 ; k++ {
307
+ ans = max (ans, dfs (i, j, k, 1 )+1 )
308
+ }
309
+ }
310
+ }
311
+ }
312
+ return ans
313
+ }
176
314
```
177
315
178
316
<!-- tabs:end -->
0 commit comments