Given an M × N binary matrix, find the size of the largest square submatrix of 1's present.

For example, the size of the largest square submatrix of 1's is 3 in the following matrix:

  0   0   1   0   1   1
  0   1   1   1   0   0
  0   0   1   1   1   1
  1   1   0   1   1   1
  1   1   1   1   1   1
  1   1   0   1   1   1
  1   0   1   1   1   1
  1   1   1   0   1   1

Practice this problem

The idea is to use dynamic programming to solve this problem. The problem has optimal substructure. The size of the largest square submatrix ending at a cell M[i][j] will be 1 plus the minimum among the largest square submatrix ending at M[i][j-1], M[i-1][j] and M[i-1][j-1]. The result will be the maximum of all square submatrix ending at M[i][j] for all possible values of i and j.

How does this works?

Let’s consider any 2×2 matrix. For it to be a 2×2 matrix, each of the top, left, and top-left neighbor of its bottom-right corner has to be a 1×1 square matrix.

Similarly, for a 3×3 matrix, each top, left, and top-left neighbor of its bottom-right corner has to be a 2×2 square matrix.

In general, for any n × n square matrix, each of its neighbors at the top left and top-left corner should at least have the size of (n-1) × (n-1). The reverse of this statement is also true. If the size of the square submatrix ending at top, left, and top-left neighbors of any cell in the given matrix is at least n-1, then we can get n × n submatrix from that cell. That is the reason behind picking up the smallest neighboring square and adding 1 to it.

The following figure might help in visualizing things better:

Maximum Square Matrix – Dynamic Programming

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

Java


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

Python


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

The time complexity of the proposed solution is exponential and occupies space in the call stack.

 
The above solution exhibits overlapping subproblems. If we draw the solution’s recursion tree, we can see that the same subproblems are repeatedly computed. We know that problems with optimal substructure and overlapping subproblems can be solved using dynamic programming, in which subproblem solutions are memoized rather than computed repeatedly. The memoized version follows the top-down approach since we first break the problem into subproblems and then calculate and store values. We can also solve this problem in a bottom-up manner. In the bottom-up approach, we solve smaller subproblems first, then solve larger subproblems from them.

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

Java


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

Python


Download  Run Code

Output:

The size of the largest square submatrix of 1’s is 3

The time complexity of the proposed solution is O(M × N) for an M × N matrix. The auxiliary space required by the program is O(M × N).

 
Exercise: Find the size of the largest rectangular submatrix of 1’s present in a given binary matrix.