Skip to content

Commit 069adfa

Browse files
committed
feat: add solutions to lc problem: No.3459
No.3459.Length of Longest V-Shaped Diagonal Segment
1 parent 58e70ed commit 069adfa

File tree

6 files changed

+491
-96
lines changed

6 files changed

+491
-96
lines changed

solution/3400-3499/3459.Length of Longest V-Shaped Diagonal Segment/README.md

Lines changed: 171 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -114,65 +114,203 @@ tags:
114114

115115
<!-- solution:start -->
116116

117-
### 方法一
117+
### 方法一:记忆化搜索
118118

119-
<!-- tabs:start -->
119+
我们设计一个函数 $\text{dfs}(i, j, k, \textit{cnt})$,表示上一个位置为 $(i, j)$,当前方向为 $k$,剩余可转向次数为 $\textit{cnt}$ 时,返回最长的 V 形对角线段长度。
120120

121-
#### Python3
121+
函数 $\text{dfs}$ 的执行逻辑如下:
122122

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$。
128124

129-
def within_bounds(i, j):
130-
return 0 <= i < m and 0 <= j < n
125+
否则,我们有两种选择:
131126

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+
遍历结束后,返回答案即可。
136135

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+
为了避免重复计算,我们使用记忆化搜索来缓存中间结果。
139137

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$ 分别是矩阵的行数和列数。
144139

145-
return result
140+
<!-- tabs:start -->
146141

147-
directions = ((1, 1), (-1, 1), (1, -1), (-1, -1))
148-
result = 0
142+
#### Python3
149143

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
156157

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
158167
```
159168

160169
#### Java
161170

162171
```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+
}
164213
```
165214

166215
#### C++
167216

168217
```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+
};
170260
```
171261

172262
#### Go
173263

174264
```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+
}
176314
```
177315

178316
<!-- tabs:end -->

0 commit comments

Comments
 (0)