Based on the “largest square in a histogram” problem (shown below), the goal is to analyze a binary 2D array consisting of ones and zeroes, and find the largest square section of the array that contains ones. This is useful for a number of tasks in statistics and image processing.

Largest rectangle in a histogram. (C) GeeksForGeeks.com – Shown under a FAIR USE exemption to the DMCA for works relating to public knowledge.
Using a “waterfall” incrementing operation, we arrive at the code shown below.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define bool int
#define R 20
#define C 20
void printMaxSubSquare(bool M[R][C]) {
int i,j;
int S[R][C];
int max_of_s, max_i, max_j;
/* Set first column of S[][]*/
for(i = 0; i < R; i++)
S[i][0] = M[i][0];
/* Set first row of S[][]*/
for(j = 0; j < C; j++)
S[0][j] = M[0][j];
/* Construct other entries of S[][]*/
for(i = 1; i < R; i++) {
for(j = 1; j < C; j++) {
if(M[i][j] == 1)
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1;
else
S[i][j] = 0;
}
}
/* Find the maximum entry, and indexes of maximum entry
in S[][] */
max_of_s = S[0][0]; max_i = 0; max_j = 0;
for(i = 0; i < R; i++)
{
for(j = 0; j < C; j++)
{
if(max_of_s < S[i][j])
{
max_of_s = S[i][j];
max_i = i;
max_j = j;
}
}
}
printf("max_of_s:%d - max_i:%d - max_j:%d\n", max_of_s, max_i, max_j);
printf("\n Maximum size sub-matrix is: \n");
for(i = max_i; i > max_i - max_of_s; i--)
{
for(j = max_j; j > max_j - max_of_s; j--)
{
printf("%d ", M[i][j]);
}
printf("\n");
}
/* Print a prettier description of our result */
for (i=0; i<R; i++) {
for (j=0; j<C; j++) {
if ((i > max_i - max_of_s) && (i <= max_i) && (j > max_j - max_of_s) && (j <= max_j)) {
printf("# ");
} else {
printf(". ");
}
}
printf("\n");
}
printf("\n");
/* Print out the sum column */
for (i=0; i<R; i++) {
for (j=0; j<C; j++) {
printf("%d ", S[i][j]);
}
printf("\n");
}
printf("\n");
}
/* UTILITY FUNCTIONS */
/* Function to get minimum of three values */
int min(int a, int b, int c)
{
int m = a;
if (m > b)
m = b;
if (m > c)
m = c;
return m;
}
/* Driver function to test above functions */
int main()
{
int i, j;
const int bias = 2; /* Set to "2" for a 50/50 random chance; Higher bias
* means a greater chance of the value being set to
* true, and a larger sub-square being likely.
*/
bool M[R][C] = { 0 };
/*
bool M[R][C] = {{0, 1, 1, 0, 1},
{1, 1, 0, 1, 0},
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{0, 0, 0, 0, 0}};
*/
srand(time(NULL));
for (i=0; i<R; i++) {
for (j=0; j<C; j++) {
M[i][j] = (rand() % bias)>=(bias-1)?0:1;
}
}
/* print overall square */
for (i=0; i<R; i++) {
for (j=0; j<C; j++) {
printf("%d ", M[i][j]);
}
printf("\n");
}
printf("\n");
printMaxSubSquare(M);
//getchar();
}
The best part about this, is by manipulating the “bias” variable, we can control the average number of ones versus zeros in the array, allowing us to see a number of different potential outcomes. With an “even” bias (ie: 50%), we see that the largest sub-square is often quite small.
0 1 0 1 0 0 1 1 1 1 1 0 0 0 1 0 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 1 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 0 0 1 1 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 0 0 1 0 max_of_s:2 - max_i:1 - max_j:7 Maximum size sub-matrix is: 1 1 1 1 . . . . . . # # . . . . . . . . . . . . . . . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0 1 0 1 0 0 1 1 1 1 1 0 0 0 1 0 1 1 1 0 1 1 1 1 0 1 1 2 2 2 0 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 2 0 0 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1 1 2 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 2 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 2 2 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 0 1 2 0 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 2 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 2 2 0 1 1 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 0 0 1 1 2 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 2 1 0 0 0 1 0 0 1 2 2 0 1 0 0 0 0 0 0 0 1 2 1 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 2 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 0 1 2 2 2 0 1 1 0 1 1 0 1 0 0 1 0
While with a modified bias (80% in the case below) we get much larger sub-squares.
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 max_of_s:14 - max_i:19 - max_j:18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . . . . . . # # # # # # # # # # # # # # . 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 2 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 2 3 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 1 2 3 1 1 2 3 4 5 6 6 6 6 0 1 2 3 4 5 6 1 2 3 2 2 2 3 4 5 6 7 7 7 1 1 2 3 4 5 6 1 2 3 3 3 3 3 4 5 6 7 8 8 2 2 2 3 4 5 6 1 2 3 4 4 4 4 4 5 6 7 8 9 3 3 3 3 4 5 6 1 2 3 4 5 5 5 5 5 6 7 8 9 4 4 4 4 4 5 6 1 2 3 4 5 6 6 6 6 6 7 8 9 5 5 5 5 5 5 6 1 2 3 4 5 6 7 7 7 7 7 8 9 6 6 6 6 6 6 6 1 2 3 4 5 6 7 8 8 8 8 8 9 7 7 7 7 7 7 7 1 2 3 4 5 6 7 8 9 9 9 9 9 8 8 8 8 8 8 8 1 2 3 4 5 6 7 8 9 10 10 10 10 9 9 9 9 9 9 9 1 0 1 2 3 4 5 6 7 8 9 10 11 10 10 10 10 10 10 10 1 1 1 2 0 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 1 2 2 2 0 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 1 2 3 3 1 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 1 2 3 4 2 2 2 3 4 5 6 7 8 9 10 11 12 13 14 14