Given a 2D grid
of 0
s and 1
s, return the number of elements in the largest square subgrid that has all 1
s on its border, or 0
if such a subgrid doesn't exist in the grid
.
Example 1:
Input: grid = [[1,1,1],[1,0,1],[1,1,1]] Output: 9
Example 2:
Input: grid = [[1,1,0,0]] Output: 1
Constraints:
1 <= grid.length <= 100
1 <= grid[0].length <= 100
grid[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:
The brute force method for finding the largest square completely surrounded by ones involves checking every possible square within the given grid. We start with the biggest possible square and then work our way down, looking at every possible position for that square within the grid.
Here's how the algorithm would work step-by-step:
def largest_1_bordered_square(grid):
rows = len(grid)
columns = len(grid[0])
max_square_side = min(rows, columns)
for current_side in range(max_square_side, 0, -1):
# Iterate through possible top-left corners for each square side
for row_start in range(rows - current_side + 1):
for column_start in range(columns - current_side + 1):
# Check if all borders of the square are ones
is_valid_square = True
for column_index in range(column_start, column_start + current_side):
if grid[row_start][column_index] == 0:
is_valid_square = False
break
if not is_valid_square:
continue
for column_index in range(column_start, column_start + current_side):
if grid[row_start + current_side - 1][column_index] == 0:
is_valid_square = False
break
if not is_valid_square:
continue
for row_index in range(row_start, row_start + current_side):
if grid[row_index][column_start] == 0:
is_valid_square = False
break
if not is_valid_square:
continue
for row_index in range(row_start, row_start + current_side):
if grid[row_index][column_start + current_side - 1] == 0:
is_valid_square = False
break
# If the square is valid, return the area
if is_valid_square:
return current_side * current_side
# If no 1-bordered square is found, return 0
return 0
The most efficient approach involves creating helper tables that store information about continuous sequences of ones. We can use these tables to quickly check if a square of a certain size exists with all ones on its border, avoiding unnecessary checks.
Here's how the algorithm would work step-by-step:
def largest_1_bordered_square(grid):
rows = len(grid)
cols = len(grid[0]) if rows > 0 else 0
left_table = [[0] * cols for _ in range(rows)]
up_table = [[0] * cols for _ in range(rows)]
for row_index in range(rows):
for col_index in range(cols):
if grid[row_index][col_index] == 1:
left_table[row_index][col_index] = (left_table[row_index][col_index - 1] if col_index > 0 else 0) + 1
up_table[row_index][col_index] = (up_table[row_index - 1][col_index] if row_index > 0 else 0) + 1
max_side = min(rows, cols)
for side_length in range(max_side, 0, -1):
for row_index in range(rows - side_length + 1):
for col_index in range(cols - side_length + 1):
# Check if all borders are 1s of the correct length.
if left_table[row_index][col_index + side_length - 1] >= side_length and \
up_table[row_index + side_length - 1][col_index] >= side_length and \
left_table[row_index + side_length - 1][col_index + side_length - 1] >= side_length and \
up_table[row_index][col_index] >= side_length:
# We found the largest, return immediately.
return side_length
# No square found.
return 0
Case | How to Handle |
---|---|
Null or empty matrix | Return 0 if the input matrix is null or has zero rows or columns, as no square can exist. |
Matrix with only one row or one column | Iterate through the single row/column to find the largest '1' and return 1 if found, otherwise 0. |
Matrix filled entirely with zeros | Return 0, as no 1-bordered square can be formed. |
Matrix filled entirely with ones | Return the minimum of the number of rows and columns since that's the maximum square size possible. |
Rectangular matrix (number of rows != number of columns) | The solution should correctly handle rectangular matrices by considering the minimum dimension when determining the maximum possible square size. |
Large matrix exceeding memory constraints | The solution should use a bottom-up dynamic programming approach that has optimal space complexity. |
Matrix with rows of varying lengths | The solution must first validate that each row has the same length before proceeding, returning an error or default value (like 0) if not. |
Integer overflow when calculating side length | Ensure calculations involving side lengths are done using `long` or a similar type to avoid overflow when dealing with maximum dimensions. |