Maximal Square

Updated on 12 June, 2025
Maximal Square header image

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.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:

  1. Initial Setup:

    • To solve this, we first create an auxiliary matrix dp of the same dimensions as the original matrix. Each cell (i, j) in dp will store the size of the largest square sub-matrix whose lower right corner is at (i, j).
  2. Fill the dp Matrix:

    • For every cell in dp, if the corresponding cell in the matrix is a 0, the value in dp should obviously be 0 because you cannot start a square of 1s 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.
  3. Edge Cases:

    • If the matrix dimension is 1x1, check directly and return 0 or 1 which concurs with the absence or presence of a 1.
    • For the first row and first column in dp, if the matrix has a 1 at these positions, that alone forms a square of side 1 sizing the area to 1.
  4. 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 of 1s. Squaring this value gives the area of the largest square.
  5. 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.

Examples:

  • Example 1 Insights:
    • The largest square of 1s ends at position (2, 4) with side 2, hence the area is 2x2 = 4.
  • Example 2 Insights:
    • The maximum side length of 1 only allows a minimal square area of 1.
  • Example 3 Insights:
    • Only 0s present, so the resultant area is 0.

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
cpp
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:

  1. Determine the number of rows (numRows) and columns (numCols) in the grid.
  2. Initialize a vector dynamicP that will store intermediate results of the dynamic programming algorithm.
  3. Use two nested loops to iterate over grid cells starting from the first row and column (using 1-based indexing inside the loop).
  4. For each cell, check if the value is '1':
    • Update dynamicP[c] using the minimum value of three adjacent cells (dynamicP[c-1], previous, and dynamicP[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.
  5. If a '0' is encountered, reset dynamicP[c] to 0.
  6. 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.

java
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.

python
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 list dp_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 in dp_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, and dp_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.
  • 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] using old_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.

Comments

No comments yet.