Given an m x n
binary matrix
filled with 0
's and 1
's, find the largest square containing only 1
's and return its area.
Example 1:
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] Output: 4
Example 2:
Input: matrix = [["0","1"],["1","0"]] Output: 1
Example 3:
Input: matrix = [["0"]] Output: 0
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[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 goal is to find the biggest square made up of only 'true' values within a grid. The brute force way means we'll check every possible square size and location to see if it fits the criteria.
Here's how the algorithm would work step-by-step:
def maximal_square_brute_force(matrix):
if not matrix:
return 0
rows = len(matrix)
cols = len(matrix[0])
max_side = 0
# Iterate through all possible square sizes
for side_length in range(1, min(rows, cols) + 1):
# Iterate through all possible top-left corners for each square size
for row_start in range(rows - side_length + 1):
for col_start in range(cols - side_length + 1):
# Check if the current square is valid.
is_square = True
for row_index in range(row_start, row_start + side_length):
for col_index in range(col_start, col_start + side_length):
if matrix[row_index][col_index] == '0':
is_square = False
break
if not is_square:
break
# Update maximal side length if applicable
if is_square:
max_side = max(max_side, side_length)
return max_side * max_side
The best way to solve this is to avoid re-calculating sizes. Instead, we build on previous calculations to determine the size of larger squares. This allows us to find the biggest square efficiently by only checking each spot once.
Here's how the algorithm would work step-by-step:
def maximal_square(matrix):
if not matrix:
return 0
number_of_rows = len(matrix)
number_of_columns = len(matrix[0])
# dp table stores max square side length ending at each cell.
dp_table = [[0] * number_of_columns for _ in range(number_of_rows)]
max_side = 0
for row_index in range(number_of_rows):
for column_index in range(number_of_columns):
if matrix[row_index][column_index] == '1':
# Base case: If at the edge, the size is 1 if it's a '1'.
if row_index == 0 or column_index == 0:
dp_table[row_index][column_index] = 1
else:
# Find the minimum side length of neighbors.
dp_table[row_index][column_index] = min(dp_table[row_index - 1][column_index],
dp_table[row_index][column_index - 1],
dp_table[row_index - 1][column_index - 1]) + 1
# Track the maximum side length found so far.
max_side = max(max_side, dp_table[row_index][column_index])
# Return the area of the largest square.
return max_side * max_side
Case | How to Handle |
---|---|
Null or empty input matrix | Return 0 immediately as there's no square to be found. |
Matrix with zero rows or zero columns | Return 0 immediately as there's no square to be found. |
Matrix with only one row or one column | Iterate through the single row/column and return 1 if any '1' is present, otherwise return 0. |
Matrix filled entirely with '0's | Return 0, as no square of 1's exists. |
Matrix filled entirely with '1's | Return the area of the entire matrix if it's a square, otherwise return the area of the largest possible square that fits within the matrix's dimensions. |
Large matrix: Potential integer overflow when calculating area | Use a data type large enough to hold the area (e.g., long) or be mindful that the maximum side length can be at most the matrix dimension. |
Non-binary input: Matrix contains values other than '0' or '1' | Treat any non-'1' value as '0' during calculation, or throw an error if the input should strictly adhere to the binary constraint. |
Very large matrix dimensions that could lead to memory issues. | Dynamic programming approach helps, but be aware of space complexity O(m*n); Optimize to potentially use only two rows for space. |