Open In App

Maximum size rectangle binary sub-matrix with all 1s

Last Updated : 26 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a 2d binary matrix mat[][], the task is to find the maximum size rectangle binary-sub-matrix with all 1’s

Examples: 

Input:
mat = [
[0, 1, 1, 0],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 0, 0] ]

Output : 8
Explanation : The largest rectangle with only 1’s is from (1, 0) to (2, 3) which is
[1, 1, 1, 1]
[1, 1, 1, 1]

Input:
mat = [
[0, 1, 1],
[1, 1, 1],
[0, 1, 1] ]

Output: 6
Explanation: The largest rectangle with only 1’s is from (0, 1) to (2, 2) which is
[1, 1]
[1, 1]
[1, 1]

There is already an algorithm discussed a dynamic programming based solution for finding the largest square with 1s

Using Largest Rectangular Area in a Histogram Approach – O(n*m) Time and O(m) Space

This approach is based on Largest Rectangular Area in a Histogram.

  • Consider each row (starting from the top row) as the base of the histogram chart formed with all 1s.
  • For each row, increase height of a bar by the amount of the previous row, only if the value in current row is 1 and calculate the largest rectangular area of that histogram.
  • The largest rectangular area of a histogram among all possible base rows is the required are of the rectangle.

Illustration: 

Input :
0 1 1 0
1 1 1 1
1 1 1 1
1 1 0 0
Step 1:
0 1 1 0 maximum area = 2
Step 2: For the remaining rows, we add previous row only if the current cell’s value is 1
row 1 1 2 2 1 area = 4, maximum area for this row becomes 4
row 2 2 3 3 2 area = 8, maximum area for this row becomes 8
row 3 3 4 0 0 area = 6, maximum area for this row remains 8

C++
// C++ program to find the maximum area of 
// rectangle in a 2D matrix.
#include <bits/stdc++.h>
using namespace std;

// Function to find the maximum area of 
// rectangle in a histogram.
int getMaxArea(vector<int>& arr) {
    int n = arr.size();
    stack<int> s;
    int res = 0;
    int tp, curr;
    for (int i = 0; i < n; i++) {      
         
        while (!s.empty() && arr[s.top()] >= arr[i]) {
          
            // The popped item is to be considered as the 
            // smallest element of the histogram
            tp = s.top(); 
            s.pop();
          
            // For the popped item previous smaller element is 
            // just below it in the stack (or current stack top)
            // and next smaller element is i
            int width = s.empty() ? i : i - s.top() - 1;
          
            res = max(res,  arr[tp] * width);
        }
        s.push(i);
    }

    // For the remaining items in the stack, next smaller does
    // not exist. Previous smaller is the item just below in
    // stack.
    while (!s.empty()) {
        tp = s.top(); s.pop();
        curr = arr[tp] * (s.empty() ? n : n - s.top() - 1);
        res = max(res, curr);
    }

    return res;
}

// Function to find the maximum area of rectangle
// in a 2D matrix.
int maxArea(vector<vector<int>> &mat) {
    int n = mat.size(), m = mat[0].size();
    
    // Array to store matrix 
    // as a histogram.
    vector<int> arr(m, 0);
    
    int ans = 0;
    
    // Traverse row by row.
    for (int i=0; i<n; i++) {
        for (int j=0; j<m; j++) {
            if (mat[i][j]==1) {
                arr[j]++;
            }
            else {
                arr[j] = 0;
            }
        }
        
        ans = max(ans, getMaxArea(arr));
    }
    
    return ans;
}

int main() {
    vector<vector<int>> mat = 
        {{0,1,1,0},
         {1,1,1,1},
         {1,1,1,1},
         {1,1,0,0}};
         
    cout << maxArea(mat) << endl;
    
    return 0;
}
Java
// Java program to find the maximum area of 
// rectangle in a 2D matrix.

import java.util.Stack;

class GfG {
    
    // Function to find the maximum area of 
    // rectangle in a histogram.
    static int getMaxArea(int[] arr) {
        int n = arr.length;
        Stack<Integer> s = new Stack<>();
        int res = 0;
        int tp, curr;

        for (int i = 0; i < n; i++) {
            while (!s.isEmpty() && arr[s.peek()] >= arr[i]) {

                // The popped item is to be considered as the 
                // smallest element of the histogram
                tp = s.pop();

                // For the popped item previous smaller element is 
                // just below it in the stack (or current stack top)
                // and next smaller element is i
                int width = s.isEmpty() ? i : i - s.peek() - 1;

                res = Math.max(res, arr[tp] * width);
            }
            s.push(i);
        }

        // For the remaining items in the stack, next smaller does
        // not exist. Previous smaller is the item just below in
        // stack.
        while (!s.isEmpty()) {
            tp = s.pop();
            curr = arr[tp] * (s.isEmpty() ? n : n - s.peek() - 1);
            res = Math.max(res, curr);
        }

        return res;
    }
    
    // Function to find the maximum area of rectangle
    // in a 2D matrix.
    static int maxArea(int[][] mat) {
        int n = mat.length, m = mat[0].length;

        // Array to store matrix 
        // as a histogram.
        int[] arr = new int[m];

        int ans = 0;

        // Traverse row by row.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1) {
                    arr[j]++;
                } else {
                    arr[j] = 0;
                }
            }

            ans = Math.max(ans, getMaxArea(arr));
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {0, 1, 1, 0},
            {1, 1, 1, 1},
            {1, 1, 1, 1},
            {1, 1, 0, 0}
        };

        System.out.println(maxArea(mat));
    }
}
Python
# Python program to find the maximum area of 
# rectangle in a 2D matrix.

# Function to find the maximum area of 
# rectangle in a histogram.
def getMaxArea(arr):
    n = len(arr)
    s = []
    res = 0

    for i in range(n):
        while s and arr[s[-1]] >= arr[i]:

            # The popped item is to be considered as the 
            # smallest element of the histogram
            tp = s.pop()

            # For the popped item previous smaller element is 
            # just below it in the stack (or current stack top)
            # and next smaller element is i
            width = i if not s else i - s[-1] - 1

            res = max(res, arr[tp] * width)
        s.append(i)

    # For the remaining items in the stack, next smaller does
    # not exist. Previous smaller is the item just below in
    # stack.
    while s:
        tp = s.pop()
        curr = arr[tp] * (n if not s else n - s[-1] - 1)
        res = max(res, curr)

    return res

# Function to find the maximum area of rectangle
# in a 2D matrix.
def maxArea(mat):
    n = len(mat)
    m = len(mat[0])

    # Array to store matrix 
    # as a histogram.
    arr = [0] * m

    ans = 0

    # Traverse row by row.
    for i in range(n):
        for j in range(m):
            if mat[i][j] == 1:
                arr[j] += 1
            else:
                arr[j] = 0

        ans = max(ans, getMaxArea(arr))

    return ans

if __name__ == "__main__":
    mat = [
        [0, 1, 1, 0],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 0, 0]
    ]

    print(maxArea(mat))
C#
// C# program to find the maximum area of 
// rectangle in a 2D matrix.

using System;
using System.Collections.Generic;

class GfG {
    
    // Function to find the maximum area of 
    // rectangle in a histogram.
    static int getMaxArea(int[] arr) {
        int n = arr.Length;
        Stack<int> s = new Stack<int>();
        int res = 0, tp, curr;

        for (int i = 0; i < n; i++) {
            while (s.Count > 0 && arr[s.Peek()] >= arr[i]) {

                // The popped item is to be considered as the 
                // smallest element of the histogram
                tp = s.Pop();

                // For the popped item previous smaller element is 
                // just below it in the stack (or current stack top)
                // and next smaller element is i
                int width = s.Count == 0 ? i : i - s.Peek() - 1;

                res = Math.Max(res, arr[tp] * width);
            }
            s.Push(i);
        }

        // For the remaining items in the stack, next smaller does
        // not exist. Previous smaller is the item just below in
        // stack.
        while (s.Count > 0) {
            tp = s.Pop();
            curr = arr[tp] * (s.Count == 0 ? n : n - s.Peek() - 1);
            res = Math.Max(res, curr);
        }

        return res;
    }
    
    // Function to find the maximum area of rectangle
    // in a 2D matrix.
    static int maxArea(int[][] mat) {
        int n = mat.Length, m = mat[0].Length;

        // Array to store matrix 
        // as a histogram.
        int[] arr = new int[m];

        int ans = 0;

        // Traverse row by row.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1) {
                    arr[j]++;
                } else {
                    arr[j] = 0;
                }
            }

            ans = Math.Max(ans, getMaxArea(arr));
        }

        return ans;
    }

    static void Main(string[] args) {
        int[][] mat = {
            new int[] {0, 1, 1, 0},
            new int[] {1, 1, 1, 1},
            new int[] {1, 1, 1, 1},
            new int[] {1, 1, 0, 0}
        };

        Console.WriteLine(maxArea(mat));
    }
}
JavaScript
// JavaScript program to find the maximum area of 
// rectangle in a 2D matrix.

// Function to find the maximum area of 
// rectangle in a histogram.
function getMaxArea(arr) {
    let n = arr.length;
    let s = [];
    let res = 0;

    for (let i = 0; i < n; i++) {
        while (s.length > 0 && arr[s[s.length - 1]] >= arr[i]) {

            // The popped item is to be considered as the 
            // smallest element of the histogram
            let tp = s.pop();

            // For the popped item previous smaller element is 
            // just below it in the stack (or current stack top)
            // and next smaller element is i
            let width = s.length === 0 ? i : i - s[s.length - 1] - 1;

            res = Math.max(res, arr[tp] * width);
        }
        s.push(i);
    }

    // For the remaining items in the stack, next smaller does
    // not exist. Previous smaller is the item just below in
    // stack.
    while (s.length > 0) {
        let tp = s.pop();
        let curr = arr[tp] * (s.length === 0 ? n : n - s[s.length - 1] - 1);
        res = Math.max(res, curr);
    }

    return res;
}

// Function to find the maximum area of rectangle
// in a 2D matrix.
function maxArea(mat) {
    let n = mat.length, m = mat[0].length;

    // Array to store matrix 
    // as a histogram.
    let arr = new Array(m).fill(0);

    let ans = 0;

    // Traverse row by row.
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 1) {
                arr[j]++;
            } else {
                arr[j] = 0;
            }
        }

        ans = Math.max(ans, getMaxArea(arr));
    }

    return ans;
}

const mat = [
    [0, 1, 1, 0],
    [1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 0, 0]
];

console.log(maxArea(mat));

Output
8

Using Dynamic Programming (Memoization) – O((n^2)*m) Time and O(n*m) Space

The idea is to store the width of consecutive 1’s ending at each cell (i, j) in a 2D array. Starting from each cell (i, j) with value 1, iterate upwards row by row, find the minimum width of 1’s in the column to ensure the rectangle remains valid. The area of the rectangle is then calculated as the minimum width multiplied by the height, updating the maximum area encountered so far.

  • Create a 2D matrix memo of size n*m, initialized to 0, to store the width of consecutive 1s ending at each cell (i, j).
  • Iterate through each cell (i, j) in the input matrix. If the value at (i, j) is 1, follow steps:
    • Set memo[i][j] = 1 if j == 0, otherwise set memo[i][j] = 1 + memo[i][j – 1].
    • Initialize width = memo[i][j].
    • For each row k from i to 0, update width = min(width, memo[k][j]) and calculate the rectangle area as width*(i – k + 1). Update the maximum area found so far.
  • Return the maximum area calculated.
C++
// C++ program to find the maximum area of
// rectangle in a 2D matrix.
#include <bits/stdc++.h>
using namespace std;

// Function to find the maximum area of rectangle
// in a 2D matrix.
int maxArea(vector<vector<int>> &mat) {
  
    int n = mat.size(), m = mat[0].size();

    // 2D matrix to store the width of 1's
    // ending at each cell.
    vector<vector<int>> memo(n, vector<int>(m, 0));
    int ans = 0;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 0)
                continue;

            // Set width of 1's at (i,j).
            if (j == 0)
                memo[i][j] = 1;
            else
                memo[i][j] = 1 + memo[i][j - 1];

            int width = memo[i][j];

            // Traverse row by row, update the
            // minimum width and calculate area.
            for (int k = i; k >= 0; k--)
            {
                width = min(width, memo[k][j]);
                int area = width * (i - k + 1);

                ans = max(ans, area);
            }
        }
    }

    return ans;
}

int main() {
    vector<vector<int>> mat = {{0, 1, 1, 0}, 
                               {1, 1, 1, 1}, 
                               {1, 1, 1, 1}, 
                               {1, 1, 0, 0}};

    cout << maxArea(mat) << endl;

    return 0;
}
Java
// Java program to find the maximum area of 
// rectangle in a 2D matrix.

class GfG {
    
    static int maxArea(int[][] mat) {
        int n = mat.length, m = mat[0].length;

        // 2D matrix to store the width of 1's 
        // ending at each cell.
        int[][] memo = new int[n][m];
        int ans = 0;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 0) continue;

                // Set width of 1's at (i,j).
                if (j == 0) memo[i][j] = 1;
                else memo[i][j] = 1 + memo[i][j - 1];

                int width = memo[i][j];

                // Traverse row by row, update the 
                // minimum width and calculate area.
                for (int k = i; k >= 0; k--) {
                    width = Math.min(width, memo[k][j]);
                    int area = width * (i - k + 1);

                    ans = Math.max(ans, area);
                }
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {0, 1, 1, 0},
            {1, 1, 1, 1},
            {1, 1, 1, 1},
            {1, 1, 0, 0}
        };

        System.out.println(maxArea(mat));
    }
}
Python
# Python program to find the maximum area of 
# rectangle in a 2D matrix.

def maxArea(mat):
    n, m = len(mat), len(mat[0])

    # 2D matrix to store the width of 1's 
    # ending at each cell.
    memo = [[0] * m for _ in range(n)]
    ans = 0

    for i in range(n):
        for j in range(m):
            if mat[i][j] == 0:
                continue

            # Set width of 1's at (i, j).
            if j == 0:
                memo[i][j] = 1
            else:
                memo[i][j] = 1 + memo[i][j - 1]

            width = memo[i][j]

            # Traverse row by row, update the 
            # minimum width and calculate area.
            for k in range(i, -1, -1):
                width = min(width, memo[k][j])
                area = width * (i - k + 1)

                ans = max(ans, area)

    return ans


if __name__ == "__main__":
    mat = [
        [0, 1, 1, 0],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 0, 0]
    ]

    print(maxArea(mat))
C#
// C# program to find the maximum area of 
// rectangle in a 2D matrix.
using System;

class GfG {
    static int maxArea(int[][] mat) {
        int n = mat.Length, m = mat[0].Length;

        // 2D matrix to store the width of 1's 
        // ending at each cell.
        int[,] memo = new int[n, m];
        int ans = 0;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 0) continue;

                // Set width of 1's at (i, j).
                if (j == 0) memo[i, j] = 1;
                else memo[i, j] = 1 + memo[i, j - 1];

                int width = memo[i, j];

                // Traverse row by row, update the 
                // minimum width and calculate area.
                for (int k = i; k >= 0; k--) {
                    width = Math.Min(width, memo[k, j]);
                    int area = width * (i - k + 1);

                    ans = Math.Max(ans, area);
                }
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int[][] mat = {
            new int[]{0, 1, 1, 0},
            new int[]{1, 1, 1, 1},
            new int[]{1, 1, 1, 1},
            new int[]{1, 1, 0, 0}
        };

        Console.WriteLine(maxArea(mat));
    }
}
JavaScript
// JavaScript program to find the maximum area of 
// rectangle in a 2D matrix.

function maxArea(mat) {
    let n = mat.length, m = mat[0].length;

    // 2D matrix to store the width of 1's 
    // ending at each cell.
    let memo = Array.from({ length: n }, () => Array(m).fill(0));
    let ans = 0;

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 0) continue;

            // Set width of 1's at (i, j).
            if (j === 0) memo[i][j] = 1;
            else memo[i][j] = 1 + memo[i][j - 1];

            let width = memo[i][j];

            // Traverse row by row, update the 
            // minimum width and calculate area.
            for (let k = i; k >= 0; k--) {
                width = Math.min(width, memo[k][j]);
                let area = width * (i - k + 1);

                ans = Math.max(ans, area);
            }
        }
    }

    return ans;
}

let mat = [
    [0, 1, 1, 0],
    [1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 0, 0]
];

console.log(maxArea(mat));

Output
8

Related articles:



Next Article

Similar Reads