In the maximal square problem we have given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s, and return its area.
Table of Contents
Example
Input:
1 0 1 0 0
0 0 1 1 1
1 1 1 1 1
0 0 0 1 0
Output:
4
Brute Force Approach
The brute force way to solve this problem is to iterate over all the possible square sub-matrix and choose the maximum from them.
C++ program for Maximal square
#include <bits/stdc++.h>
using namespace std;
int maximalSquare(vector<vector<char>> &matrix)
{
int answer = 0;
int n = matrix.size();
if (n == 0)
{
return 0;
}
int m = matrix[0].size();
if (m == 0)
{
return 0;
}
for (int sidelength = 1; sidelength <= min(n, m); sidelength++) // sidelength denotes the side length of the sub-matrix
{
// i,j are the top left index of the current sub-matrix
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if ((i + sidelength > n) or (j + sidelength > m)) //check if the current sub-matrix is not out of bounds
{
continue;
}
bool zero = false;
// check if this sub matrix contain any zero or not
for (int x = i; x < i + sidelength; x++)
{
for (int y = j; y < j + sidelength; y++)
{
if (matrix[x][y] == '0')
{
zero = true;
}
}
}
if (zero == false) // if this does not contain any zero than this is a valid sub matrix
{
answer = max(answer, sidelength * sidelength);
}
}
}
}
return answer;
}
int main()
{
int n, m;
cin >> n >> m;
vector<vector<char>> matrix(n, vector<char>(m));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
}
int answer = maximalSquare(matrix);
cout << answer << endl;
return 0;
}
4 4 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 1
4
JAVA program for Maximal square
import java.util.*;
public class Main
{
public static int maximalSquare(char[][] matrix)
{
int answer = 0;
int n = matrix.length;
if (n == 0)
{
return 0;
}
int m = matrix[0].length;
if (m == 0)
{
return 0;
}
for (int sidelength = 1; sidelength <= Math.min(n, m); sidelength++) // sidelength denotes the side length of the sub-matrix
{
// i,j are the top left index of the current sub-matrix
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if ((i + sidelength > n) || (j + sidelength > m)) //check if the current sub-matrix is not out of bounds
{
continue;
}
boolean zero = false;
// check if this sub matrix contain any zero or not
for (int x = i; x < i + sidelength; x++)
{
for (int y = j; y < j + sidelength; y++)
{
if (matrix[x][y] == '0')
{
zero = true;
}
}
}
if (zero == false) // if this does not contain any zero than this is a valid sub matrix
{
answer = Math.max(answer, sidelength * sidelength);
}
}
}
}
return answer;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();;
char[][] matrix = new char[n][m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = sc.next().charAt(0);
}
}
int answer = maximalSquare(matrix);
System.out.println(answer);
}
}
4 5 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
9
Complexity Analysis
Time complexity
As we iterate over all the squares and there will be approx N^2 squares so the total time complexity is O(N^4).
Space complexity
As we have not used any extra space so the space complexity is O(1).
Dynamic Programming Approach
Explanation
Let say we have a dp array of size (n+1,m+1) where dp[i][j] represents the largest side length of a square of all ones whose top left corner is I,j.
So, if matrix[i][j] is one than we can say dp[i][j]=1+min(dp[i-1],dp[i][j-1],dp[i-1][j-1]) because the largest square of ones with top left corner I,j is just intersection of the largest squares of ones with top left corner (i-1,j),(I,j-1),(i-1,j-1).
Algorithm
- Initialize a dp array of size (n+1,m+1) with zeroes.
- Initialize a integer ans with zero.
- Iterate over all cells of the matrix.
- If matrix[i][j] is one than update dp[i][j]=1+ min(dp[i-1],dp[i][j-1],dp[i-1][j-1]).
- Update ans=max(ans,dp[i][j]).
- Return ans.
For example:
Matrix[][]={{‘1’, ‘0’, ‘1’, ‘0’, ‘0’},
{‘1’, ‘0’, ‘1’, ‘1’, ‘1’},
{ ‘1’, ‘1’, ‘1’, ‘1’, ‘1’},
{‘1’, ‘0’, ‘0’, ‘1’, ‘0’}}
For this matrix, the dp[][] array which look like this:

dp[i][j] denotes the side length of the maximum square of ones whose top left corner has the index (i, j).
C++ program for Maximal square
#include <bits/stdc++.h>
using namespace std;
int maximalSquare(vector<vector<char>> &matrix)
{
int n = matrix.size();
if (n == 0)
{
return 0;
}
int m = matrix[0].size();
if (m == 0)
{
return 0;
}
int ans = 0;
vector<vector<int>> dp(n, vector<int>(m, 0));
for (int i = n - 1; i >= 0; i--)
{
if (matrix[i][m - 1] == '1')
{
dp[i][m - 1]++;
ans = 1;
}
}
for (int i = m - 1; i >= 0; i--)
{
if (matrix[n - 1][i] == '1')
{
dp[n - 1][i]++;
ans = 1;
}
}
for (int i = n - 2; i >= 0; i--)
{
for (int j = m - 2; j >= 0; j--)
{
if (matrix[i][j] == '1')
{
dp[i][j] = min(dp[i + 1][j + 1], min(dp[i + 1][j], dp[i][j + 1])) + 1;
ans = max(ans, dp[i][j]);
}
}
}
return ans * ans;
}
int main()
{
int n, m;
cin >> n >> m;
vector<vector<char>> matrix(n, vector<char>(m));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
}
int answer = maximalSquare(matrix);
cout << answer << endl;
return 0;
}
4 2 1 0 1 1 1 1 1 0
4
JAVA program for Maximal square
import java.util.*;
public class Main
{
public static int maximalSquare(char[][] matrix)
{
int n = matrix.length;
if (n == 0)
{
return 0;
}
int m = matrix[0].length;
if (m == 0)
{
return 0;
}
int ans = 0;
int[][] dp = new int[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
dp[i][j]=0;
}
}
for (int i = n - 1; i >= 0; i--)
{
if (matrix[i][m - 1] == '1')
{
dp[i][m - 1]++;
ans = 1;
}
}
for (int i = m - 1; i >= 0; i--)
{
if (matrix[n - 1][i] == '1')
{
dp[n - 1][i]++;
ans = 1;
}
}
for (int i = n - 2; i >= 0; i--)
{
for (int j = m - 2; j >= 0; j--)
{
if (matrix[i][j] == '1')
{
dp[i][j] = Math.min(dp[i + 1][j + 1], Math.min(dp[i + 1][j], dp[i][j + 1])) + 1;
ans = Math.max(ans, dp[i][j]);
}
}
}
return ans * ans;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();;
char[][] matrix = new char[n][m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = sc.next().charAt(0);
}
}
int answer = maximalSquare(matrix);
System.out.println(answer);
}
}
4 5 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
16
Complexity Analysis
Time complexity
As we iterate over the matrix only once so the time complexity is O(N^2).
Space complexity
We took a dp array of size (n+1,m+1) so the space complexity is O(N^N).