
Problem Statement
In the given problem, you are provided with a two-dimensional binary matrix, which is only filled with the characters 0
and 1
. Your task is to identify the largest square sub-matrix entirely composed of 1
s and determine its area. The area is defined as the number of 1
s in the square, which equates to the square of the side length of the largest square found in the matrix. We will leverage the given matrix dimensions and values to solve this problem efficiently within the constraints.
Examples
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'
.
Approach and Intuition
The premise behind solving this problem is to employ dynamic programming to reduce redundant calculations:
Initial Setup:
- To solve this, we first create an auxiliary matrix
dp
of the same dimensions as the original matrix. Each cell(i, j)
indp
will store the size of the largest square sub-matrix whose lower right corner is at(i, j)
.
- To solve this, we first create an auxiliary matrix
Fill the dp Matrix:
- For every cell in
dp
, if the corresponding cell in thematrix
is a0
, the value indp
should obviously be0
because you cannot start a square of1
s at that cell. - If it is a
1
, you can potentially extend the squares ending at(i-1, j)
,(i, j-1)
, and(i-1, j-1)
. Hence,dp[i][j]
would be the minimum of these three cells plus one. This represents the new square formed by adding the(i, j)
cell to those squares.
- For every cell in
Edge Cases:
- If the matrix dimension is
1x1
, check directly and return0
or1
which concurs with the absence or presence of a1
. - For the first row and first column in
dp
, if the matrix has a1
at these positions, that alone forms a square of side 1 sizing the area to1
.
- If the matrix dimension is
Compute the Maximum:
- After building the
dp
matrix, scan through it to find the maximum value which represents the side length of the largest square of1
s. Squaring this value gives the area of the largest square.
- After building the
Optimize by Space:
- Note that updating the
dp
array only requires knowledge of the previous row and the current row, so one could optimize the space complexity to be linear relative to the number of columns.
- Note that updating the
Examples:
- Example 1 Insights:
- The largest square of
1
s ends at position(2, 4)
with side2
, hence the area is2x2 = 4
.
- The largest square of
- Example 2 Insights:
- The maximum side length of
1
only allows a minimal square area of1
.
- The maximum side length of
- Example 3 Insights:
- Only
0
s present, so the resultant area is0
.
- Only
This dynamic programming approach efficiently computes the largest square area, adheres to the constraints, and systematically uses prior results to construct new values, culminating in substantial computational savings.
Solutions
- C++
- Java
- Python
class Solution {
public:
int largestSquare(vector<vector<char>>& grid) {
int numRows = grid.size();
int numCols = numRows > 0 ? grid[0].size() : 0;
vector<int> dynamicP(numCols + 1, 0);
int largestLength = 0, previous = 0;
for (int r = 1; r <= numRows; ++r) {
for (int c = 1; c <= numCols; ++c) {
int temp = dynamicP[c];
if (grid[r - 1][c - 1] == '1') {
dynamicP[c] = min(min(dynamicP[c - 1], previous), dynamicP[c]) + 1;
largestLength = max(largestLength, dynamicP[c]);
} else {
dynamicP[c] = 0;
}
previous = temp;
}
}
return largestLength * largestLength;
}
};
In this solution summary, you will understand how to tackle the problem of finding the area of the largest square containing only 1s in a 2D binary matrix using C++.
The function largestSquare
takes a 2D vector of characters named grid
representing the binary matrix and aims to determine the area of the largest square sub-grid where every cell contains '1'.
The process involves several key steps:
- Determine the number of rows (
numRows
) and columns (numCols
) in the grid. - Initialize a vector
dynamicP
that will store intermediate results of the dynamic programming algorithm. - Use two nested loops to iterate over grid cells starting from the first row and column (using 1-based indexing inside the loop).
- For each cell, check if the value is '1':
- Update
dynamicP[c]
using the minimum value of three adjacent cells (dynamicP[c-1]
,previous
, anddynamicP[c]
) from the previous iteration, then add 1. This represents the edge length of the largest square possible at that cell. - Track and update the maximum edge length (
largestLength
) found so far.
- Update
- If a '0' is encountered, reset
dynamicP[c]
to 0. - Convert the edge length of the largest square to its area by squaring
largestLength
before returning.
This solution uses a dynamic programming technique that leverages a temporary vector for space efficiency. Important variables include largestLength
for tracking the largest square found and previous
for storing the northwest diagonal value necessary for the dynamic programming transition. The final result is the area of the largest square found in the matrix, calculated by squaring largestLength
.
public class Solution {
public int largestSquareArea(char[][] grid) {
int rows = grid.length, columns = rows > 0 ? grid[0].length : 0;
int[] computation = new int[columns + 1];
int largest = 0, before = 0;
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= columns; c++) {
int temp = computation[c];
if (grid[r - 1][c - 1] == '1') {
computation[c] = Math.min(Math.min(computation[c - 1], before), computation[c]) + 1;
largest = Math.max(largest, computation[c]);
} else {
computation[c] = 0;
}
before = temp;
}
}
return largest * largest;
}
}
Maximal Square is a problem where the goal is to find the largest square containing only 1's in a 2D binary matrix and return its area. The solution provided here implements a dynamic programming approach to solve this problem efficiently.
Initially, declare a method largestSquareArea
which takes a 2D array of characters (grid
) representing the binary matrix. Determine the dimensions of the matrix and initialize variables to store the size of the largest square (largest
) and the previous computation result (before
). A temporary array (computation
) is used to store interim results for each column across all rows.
Iterate over each row and within that, iterate over each column of the grid. Using dynamic programming, update the computation
array to determine the size of the largest square ending at each position. This involves checking the minimum value among the left (computation[c-1]
), top (before
), and top-left diagonal (computation[c]
) elements, then adding 1 if the current cell is 1
. The result for each position is squared (since it represents the side length of the square) to update the largest
if it's the new maximum.
The computation for each cell is reset to 0
when a 0
is encountered in the grid to ensure that non-square forming cells don't affect subsequent calculations.
Finally, return the area of the largest square found (largest * largest
), where largest
represents the side length of the largest square of 1's.
This approach efficiently calculates the largest possible square in the given binary matrix with a time complexity approximately O(rows * columns), making it suitable for large inputs.
class Solution:
def largestSquare(self, grid):
num_rows = len(grid)
num_cols = len(grid[0]) if num_rows > 0 else 0
dp_table = [0] * (num_cols + 1)
max_square_len = 0
old_val = 0
for row in range(1, num_rows + 1):
for col in range(1, num_cols + 1):
temp = dp_table[col]
if grid[row - 1][col - 1] == "1":
dp_table[col] = min(dp_table[col - 1], old_val, dp_table[col]) + 1
max_square_len = max(max_square_len, dp_table[col])
else:
dp_table[col] = 0
old_val = temp
return max_square_len * max_square_len
The Python3 program provided defines a method to find the area of the largest square containing all ones in a binary matrix, referred to as grid
. Here's how the solution works:
- Initialize essential variables to store the number of rows (
num_rows
) and columns (num_cols
) of the grid. Create a listdp_table
to use as a dynamic programming table, with an additional space for simplified indexing (size =num_cols + 1
). - Set up
max_square_len
to keep track of the size of the largest square found. Another helper variable,old_val
, is used to temporarily hold previous values indp_table
during updates. - Iterate through each cell of the grid, starting from the first row and first column, as dynamic programming requires 1-based indexing for ease.
- For each cell in the grid that contains '1':
- Calculate the minimum of the three neighboring cells (
dp_table[col-1]
,old_val
, anddp_table[col]
) and add one. This calculates how large a square with the bottom-right corner in the current cell could be. - Update
max_square_len
if the newly calculated square is larger. - Update
dp_table[col]
with the new value.
- Calculate the minimum of the three neighboring cells (
- If the cell contains '0', reset
dp_table[col]
to 0, as no square can end here. - Keep a copy of the previous value
dp_table[col]
usingold_val
before moving on to the next column. - After processing all cells, the maximum length of the square's side found is multiplied by itself to give the area of the maximum square, which is then returned.
This solution employs dynamic programming to effectively calculate the maximum square area in an efficient manner, iterating through the grid once and utilizing O(n) space, where n is the number of columns.
No comments yet.