
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 1s and determine its area. The area is defined as the number of 1s 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.lengthn == matrix[i].length1 <= m, n <= 300matrix[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
dpof the same dimensions as the original matrix. Each cell(i, j)indpwill 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 thematrixis a0, the value indpshould obviously be0because you cannot start a square of1s 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 return0or1which concurs with the absence or presence of a1. - For the first row and first column in
dp, if the matrix has a1at 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
dpmatrix, scan through it to find the maximum value which represents the side length of the largest square of1s. Squaring this value gives the area of the largest square.
- After building the
Optimize by Space:
- Note that updating the
dparray 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
1s ends at position(2, 4)with side2, hence the area is2x2 = 4.
- The largest square of
- Example 2 Insights:
- The maximum side length of
1only allows a minimal square area of1.
- The maximum side length of
- Example 3 Insights:
- Only
0s 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
dynamicPthat 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
largestLengthbefore 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_tableto use as a dynamic programming table, with an additional space for simplified indexing (size =num_cols + 1). - Set up
max_square_lento keep track of the size of the largest square found. Another helper variable,old_val, is used to temporarily hold previous values indp_tableduring 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_lenif 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_valbefore 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.