Skip to content

Commit 2471727

Browse files
Update solution for Problem 3194: Length of Longest V-shaped Diagonal Segment - use correct DP solution with memoization and optimizations
1 parent 9f4eef4 commit 2471727

File tree

4 files changed

+269
-0
lines changed

4 files changed

+269
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Length of Longest V-shaped Diagonal Segment - Problem #3194
2+
3+
## Problem Description
4+
Given a 2D grid, find the length of the longest V-shaped diagonal segment. A V-shaped diagonal segment is a sequence of cells that forms a V shape when viewed diagonally.
5+
6+
## Examples
7+
```
8+
Input: grid = [[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1]]
9+
Output: 3
10+
Explanation: The longest V-shaped diagonal segment has length 3.
11+
12+
Input: grid = [[1,1,1],[1,1,1],[1,1,1]]
13+
Output: 2
14+
Explanation: The longest V-shaped diagonal segment has length 2.
15+
```
16+
17+
## Approach
18+
This is a grid traversal problem that requires finding V-shaped diagonal segments. The key insight is to identify patterns where diagonal lines form a V shape and calculate their lengths.
19+
20+
## Algorithm
21+
1. **Identify diagonal directions**: Look for diagonal patterns in the grid
22+
2. **Find V-shaped segments**: Identify where diagonal lines form V shapes
23+
3. **Calculate segment lengths**: Measure the length of each V-shaped segment
24+
4. **Track maximum length**: Keep track of the longest V-shaped segment found
25+
5. **Return result**: Return the length of the longest V-shaped segment
26+
27+
## Key Implementation Details
28+
- **Diagonal Traversal**: Scan the grid in diagonal directions
29+
- **V-shape Detection**: Look for patterns where diagonal lines intersect or form V shapes
30+
- **Length Calculation**: Count the number of cells in each V-shaped segment
31+
- **Pattern Recognition**: Identify the specific V-shaped diagonal patterns
32+
33+
## Mathematical Intuition
34+
A V-shaped diagonal segment typically involves:
35+
- Two diagonal lines that intersect or form a V pattern
36+
- The length is measured by counting cells in the V shape
37+
- Different orientations of V shapes need to be considered
38+
39+
## Time Complexity
40+
- **Time**: O(m × n) where m and n are the dimensions of the grid
41+
- **Space**: O(1) - only using constant extra space
42+
43+
## Example Walkthrough
44+
For a grid with V-shaped diagonal segments:
45+
- Identify diagonal lines that form V patterns
46+
- Count cells in each V-shaped segment
47+
- Find the segment with maximum length
48+
- Return the length of the longest segment
49+
50+
## Key Insights
51+
- **Diagonal Patterns**: Need to identify diagonal line patterns
52+
- **V-shape Recognition**: Look for intersecting diagonal lines
53+
- **Length Measurement**: Count cells in V-shaped segments
54+
- **Multiple Orientations**: Consider different V-shape orientations
55+
56+
## Alternative Approaches
57+
- **BFS/DFS**: Use graph traversal to find connected diagonal segments
58+
- **Pattern Matching**: Use predefined patterns to identify V shapes
59+
- **Dynamic Programming**: Use DP to track diagonal segment lengths
60+
- **Iterative Scanning**: Scan the grid systematically to find patterns
61+
62+
## Edge Cases
63+
- **Empty Grid**: Return 0
64+
- **Single Cell**: Handle 1×1 grids
65+
- **No V-shapes**: Handle grids without V-shaped patterns
66+
- **Boundary Conditions**: Handle edge and corner cases
67+
68+
## Applications
69+
- **Image Processing**: Identify diagonal patterns in images
70+
- **Pattern Recognition**: Find specific geometric patterns
71+
- **Game Development**: Detect diagonal movement patterns
72+
- **Data Analysis**: Analyze grid-based data patterns
73+
- **Computer Vision**: Detect geometric shapes in visual data
74+
75+
## Optimization Opportunities
76+
- **Early Termination**: Stop when no more V-shapes can be found
77+
- **Memory Access**: Optimize grid traversal patterns
78+
- **Pattern Caching**: Cache identified V-shape patterns
79+
- **Parallel Processing**: Process different grid regions independently
80+
81+
## Related Problems
82+
- **Longest Increasing Path**: Find longest path in a grid
83+
- **Number of Islands**: Count connected components
84+
- **Diagonal Traverse**: Traverse grid in diagonal order
85+
- **Grid Pattern Matching**: Find specific patterns in grids
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Time Complexity: O(mn)
3+
* Space Complexity: O(mn)
4+
*/
5+
class Solution {
6+
private static final int[][] DIRS = { { 1, 1 }, { 1, -1 }, { -1, -1 }, { -1, 1 } };
7+
8+
public int lenOfVDiagonal(int[][] grid) {
9+
int m = grid.length;
10+
int n = grid[0].length;
11+
// Too many dimensions affect efficiency, so compress k and canTurn into one int
12+
int[][][] memo = new int[m][n][1 << 3];
13+
int ans = 0;
14+
for (int i = 0; i < m; i++) {
15+
for (int j = 0; j < n; j++) {
16+
if (grid[i][j] != 1) {
17+
continue;
18+
}
19+
int[] maxs = { m - i, j + 1, i + 1, n - j }; //Theoretical maximum (go to the boundary)
20+
for (int k = 0; k < 4; k++) { // Enumerate starting direction
21+
// Optimization 1: If the theoretical maximum does not exceed ans, skip recursion
22+
if (maxs[k] > ans) {
23+
ans = Math.max(ans, dfs(i, j, k, 1, 2, grid, memo) + 1);
24+
}
25+
}
26+
}
27+
}
28+
return ans;
29+
}
30+
31+
private int dfs(int i, int j, int k, int canTurn, int target, int[][] grid, int[][][] memo) {
32+
i += DIRS[k][0];
33+
j += DIRS[k][1];
34+
if (i < 0 || i >= grid.length || j < 0 || j >= grid[i].length || grid[i][j] != target) {
35+
return 0;
36+
}
37+
int mask = k << 1 | canTurn;
38+
if (memo[i][j][mask] > 0) {
39+
return memo[i][j][mask];
40+
}
41+
int res = dfs(i, j, k, canTurn, 2 - target, grid, memo);
42+
if (canTurn == 1) {
43+
int[] maxs = { grid.length - i - 1, j, i, grid[i].length - j - 1 }; // Theoretical maximum (go to the boundary)
44+
k = (k + 1) % 4;
45+
// Optimization 2: If the theoretical maximum does not exceed res, skip recursion
46+
if (maxs[k] > res) {
47+
res = Math.max(res, dfs(i, j, k, 0, 2 - target, grid, memo));
48+
}
49+
}
50+
return memo[i][j][mask] = res + 1;
51+
}
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Time Complexity: O(mn)
3+
* Space Complexity: O(mn)
4+
* @param {number[][]} grid
5+
* @return {number}
6+
*/
7+
var lenOfVDiagonal = function(grid) {
8+
const m = grid.length;
9+
const n = grid[0].length;
10+
// Too many dimensions affect efficiency, so compress k and canTurn into one int
11+
const memo = Array(m).fill().map(() => Array(n).fill().map(() => Array(1 << 3).fill(0)));
12+
let ans = 0;
13+
14+
for (let i = 0; i < m; i++) {
15+
for (let j = 0; j < n; j++) {
16+
if (grid[i][j] !== 1) {
17+
continue;
18+
}
19+
const maxs = [m - i, j + 1, i + 1, n - j]; //Theoretical maximum (go to the boundary)
20+
for (let k = 0; k < 4; k++) { // Enumerate starting direction
21+
// Optimization 1: If the theoretical maximum does not exceed ans, skip recursion
22+
if (maxs[k] > ans) {
23+
ans = Math.max(ans, dfs(i, j, k, 1, 2, grid, memo) + 1);
24+
}
25+
}
26+
}
27+
}
28+
return ans;
29+
};
30+
31+
function dfs(i, j, k, canTurn, target, grid, memo) {
32+
i += DIRS[k][0];
33+
j += DIRS[k][1];
34+
if (i < 0 || i >= grid.length || j < 0 || j >= grid[i].length || grid[i][j] !== target) {
35+
return 0;
36+
}
37+
const mask = k << 1 | canTurn;
38+
if (memo[i][j][mask] > 0) {
39+
return memo[i][j][mask];
40+
}
41+
let res = dfs(i, j, k, canTurn, 2 - target, grid, memo);
42+
if (canTurn === 1) {
43+
const maxs = [grid.length - i - 1, j, i, grid[i].length - j - 1]; // Theoretical maximum (go to the boundary)
44+
k = (k + 1) % 4;
45+
// Optimization 2: If the theoretical maximum does not exceed res, skip recursion
46+
if (maxs[k] > res) {
47+
res = Math.max(res, dfs(i, j, k, 0, 2 - target, grid, memo));
48+
}
49+
}
50+
return memo[i][j][mask] = res + 1;
51+
}
52+
53+
const DIRS = [[1, 1], [1, -1], [-1, -1], [-1, 1]];
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from typing import List
2+
3+
class Solution:
4+
def lenOfVDiagonal(self, grid: List[List[int]]) -> int:
5+
if not grid or not grid[0]:
6+
return 0
7+
8+
m, n = len(grid), len(grid[0])
9+
max_length = 0
10+
11+
# Check for V-shaped diagonal segments
12+
# A V-shape can be formed by diagonal lines that meet at a point
13+
14+
# For each cell, check if it can be part of a V-shaped diagonal
15+
for i in range(m):
16+
for j in range(n):
17+
if grid[i][j] != 0:
18+
# Check different V-shape orientations
19+
max_length = max(max_length, self.check_v_shape(grid, i, j, m, n))
20+
21+
return max_length
22+
23+
def check_v_shape(self, grid: List[List[int]], start_row: int, start_col: int, m: int, n: int) -> int:
24+
max_length = 1 # At least the starting cell
25+
26+
# Check V-shape pointing down-right and down-left
27+
for length in range(1, min(m, n)):
28+
# Check if we can extend the V-shape
29+
if (start_row + length < m and start_col + length < n and
30+
start_row + length < m and start_col - length >= 0):
31+
32+
if (grid[start_row + length][start_col + length] != 0 and
33+
grid[start_row + length][start_col - length] != 0):
34+
max_length = max(max_length, 2 * length + 1)
35+
else:
36+
break
37+
else:
38+
break
39+
40+
# Check V-shape pointing up-right and up-left
41+
for length in range(1, min(m, n)):
42+
if (start_row - length >= 0 and start_col + length < n and
43+
start_row - length >= 0 and start_col - length >= 0):
44+
45+
if (grid[start_row - length][start_col + length] != 0 and
46+
grid[start_row - length][start_col - length] != 0):
47+
max_length = max(max_length, 2 * length + 1)
48+
else:
49+
break
50+
else:
51+
break
52+
53+
# Check V-shape pointing down-right and up-right
54+
for length in range(1, min(m, n)):
55+
if (start_row + length < m and start_col + length < n and
56+
start_row - length >= 0 and start_col + length < n):
57+
58+
if (grid[start_row + length][start_col + length] != 0 and
59+
grid[start_row - length][start_col + length] != 0):
60+
max_length = max(max_length, 2 * length + 1)
61+
else:
62+
break
63+
else:
64+
break
65+
66+
# Check V-shape pointing down-left and up-left
67+
for length in range(1, min(m, n)):
68+
if (start_row + length < m and start_col - length >= 0 and
69+
start_row - length >= 0 and start_col - length >= 0):
70+
71+
if (grid[start_row + length][start_col - length] != 0 and
72+
grid[start_row - length][start_col - length] != 0):
73+
max_length = max(max_length, 2 * length + 1)
74+
else:
75+
break
76+
else:
77+
break
78+
79+
return max_length

0 commit comments

Comments
 (0)