Given an m x n binary matrix mat, return the length of the longest line of consecutive one in the matrix.
The line could be horizontal, vertical, diagonal, or anti-diagonal.
Example 1:
Input: mat = [[0,1,1,0],[0,1,1,0],[0,0,0,1]] Output: 3
Example 2:
Input: mat = [[1,1,1,1],[0,1,1,0],[0,0,0,1]] Output: 4
Constraints:
m == mat.lengthn == mat[i].length1 <= m, n <= 200mat[i][j] is 0 or 1.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We are given a grid of zeros and ones, and we want to find the longest line of consecutive ones. The brute force way is to check every possible line, in every possible direction, to see how many consecutive ones there are.
Here's how the algorithm would work step-by-step:
def longest_line_of_consecutive_one_brute_force(matrix):
rows = len(matrix)
cols = len(matrix[0]) if rows > 0 else 0
max_length = 0
for row_index in range(rows):
for col_index in range(cols):
if matrix[row_index][col_index] == 1:
# Check right
current_length = 0
for k in range(col_index, cols):
if matrix[row_index][k] == 1:
current_length += 1
else:
break
max_length = max(max_length, current_length)
# Check down
current_length = 0
for k in range(row_index, rows):
if matrix[k][col_index] == 1:
current_length += 1
else:
break
max_length = max(max_length, current_length)
# Check diagonal down-right
current_length = 0
k = 0
while row_index + k < rows and col_index + k < cols:
if matrix[row_index + k][col_index + k] == 1:
current_length += 1
k += 1
else:
break
max_length = max(max_length, current_length)
# Check diagonal down-left
current_length = 0
# Need to check the diagonal to the left
k = 0
while row_index + k < rows and col_index - k >= 0:
if matrix[row_index + k][col_index - k] == 1:
current_length += 1
k += 1
else:
break
max_length = max(max_length, current_length)
return max_lengthThe most efficient way to find the longest line of ones is to use a technique similar to dynamic programming, building up results from smaller subproblems. Instead of recalculating lengths for each possible line direction, we store and reuse previous calculations. This allows us to efficiently determine the longest line in horizontal, vertical, and diagonal directions.
Here's how the algorithm would work step-by-step:
def longest_line(matrix):
if not matrix:
return 0
rows = len(matrix)
cols = len(matrix[0])
longest_streak = 0
# Create DP tables for each direction
horizontal_lines = [[0] * cols for _ in range(rows)]
vertical_lines = [[0] * cols for _ in range(rows)]
diagonal_lines = [[0] * cols for _ in range(rows)]
anti_diagonal_lines = [[0] * cols for _ in range(rows)]
for row_index in range(rows):
for col_index in range(cols):
if matrix[row_index][col_index] == 1:
# Update horizontal line length
if col_index > 0:
horizontal_lines[row_index][col_index] = horizontal_lines[row_index][col_index - 1] + 1
else:
horizontal_lines[row_index][col_index] = 1
# Update vertical line length
if row_index > 0:
vertical_lines[row_index][col_index] = vertical_lines[row_index - 1][col_index] + 1
else:
vertical_lines[row_index][col_index] = 1
# Diagonal line calculation
if row_index > 0 and col_index > 0:
diagonal_lines[row_index][col_index] = diagonal_lines[row_index - 1][col_index - 1] + 1
else:
diagonal_lines[row_index][col_index] = 1
# Anti-diagonal line calculation
if row_index > 0 and col_index < cols - 1:
anti_diagonal_lines[row_index][col_index] = anti_diagonal_lines[row_index - 1][col_index + 1] + 1
else:
anti_diagonal_lines[row_index][col_index] = 1
longest_streak = max(longest_streak,
horizontal_lines[row_index][col_index],
vertical_lines[row_index][col_index],
diagonal_lines[row_index][col_index],
anti_diagonal_lines[row_index][col_index])
# The accumulated maximum length is the final result
return longest_streak| Case | How to Handle |
|---|---|
| Null or empty matrix | Return 0 immediately as there are no elements to form a line. |
| Matrix with zero rows or zero columns | Return 0 immediately as there are no elements to form a line. |
| Matrix with only one row and/or one column | Iterate through the row/column and count consecutive 1s, returning the maximum count. |
| Matrix filled with all 0s | The algorithm should correctly return 0 as there are no consecutive 1s. |
| Matrix filled with all 1s | The result should be the maximum of rows/columns, or the length of the diagonal, as all are consecutive. |
| Large matrix (potential memory issues with dynamic programming solutions) | Optimize the solution to use constant space or consider streaming/iterative approaches to avoid storing the entire matrix state. |
| Integer overflow when counting long consecutive sequences | Use a data type that can accommodate the maximum possible length of a consecutive sequence (e.g., long). |
| Matrix with extremely skewed distribution of 1s, favoring one direction | The algorithm needs to efficiently handle cases where the longest line is only in one of the four directions without unnecessary computations. |