Maximum Area Rectangle of 1s in a Binary Matrix

Last Updated : 29 Jul, 2026

Given a 2D binary matrix mat[][] consisting only of 0s and 1s, find the area of the largest rectangle sub-matrix that contains only 1s.

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 of 1's highlighted in green, matching the area of 2 * 4 = 8.

2056958495


Input: mat[][] = [[0, 1, 1], [1, 1, 1], [0, 1, 1]]
Output: 6
Explanation: The largest rectangle of 1's highlighted in green, matching the area of 3 * 2 = 6.

2056958494
Try It Yourself
redirect icon

[Naive Approach] Check All Possible Rectangles - O(n ^ 2 * m ^2 * n * m) Time and O(1) Space

The idea is to generate every possible rectangle in the matrix by choosing its top-left and bottom-right corners. For each rectangle, check whether all its cells contain 1. If yes, compute its area and update the maximum area. Finally, return the largest valid rectangle found.

Working of Approach:

  • Generate every possible rectangle using four nested loops.
  • For each rectangle, traverse all its cells.
  • If every cell is 1, compute its area.
  • Update the maximum rectangle area.
  • Return the maximum area after checking all rectangles.
C++
#include <iostream>
#include <vector>
using namespace std;

// Function to find the maximum rectangle area.
int maxArea(vector<vector<int>> &mat)
{

    int n = mat.size();
    int m = mat[0].size();

    int res = 0;

    // Choose the top-left corner.
    for (int top = 0; top < n; top++)
    {
        for (int left = 0; left < m; left++)
        {

            // Choose the bottom-right corner.
            for (int bottom = top; bottom < n; bottom++)
            {
                for (int right = left; right < m; right++)
                {

                    bool valid = true;

                    // Check whether all cells inside
                    // the rectangle are 1.
                    for (int i = top; i <= bottom && valid; i++)
                    {
                        for (int j = left; j <= right; j++)
                        {
                            if (mat[i][j] == 0)
                            {
                                valid = false;
                                break;
                            }
                        }
                    }

                    // Update the maximum area if the rectangle
                    // contains only 1's.
                    if (valid)
                    {
                        int area = (bottom - top + 1) * (right - left + 1);
                        res = max(res, area);
                    }
                }
            }
        }
    }

    return res;
}

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);

    return 0;
}
Java
import java.util.*;

class GFG {

    // Function to find the maximum rectangle area.
    public int maxArea(int[][] mat)
    {

        int n = mat.length;
        int m = mat[0].length;

        int res = 0;

        // Choose the top-left corner.
        for (int top = 0; top < n; top++) {
            for (int left = 0; left < m; left++) {

                // Choose the bottom-right corner.
                for (int bottom = top; bottom < n;
                     bottom++) {
                    for (int right = left; right < m;
                         right++) {

                        boolean valid = true;

                        // Check whether all cells inside
                        // the rectangle are 1.
                        for (int i = top;
                             i <= bottom && valid; i++) {
                            for (int j = left; j <= right;
                                 j++) {
                                if (mat[i][j] == 0) {
                                    valid = false;
                                    break;
                                }
                            }
                        }

                        // Update the maximum area if the
                        // rectangle contains only 1's.
                        if (valid) {
                            int area = (bottom - top + 1)
                                       * (right - left + 1);
                            res = Math.max(res, area);
                        }
                    }
                }
            }
        }

        return res;
    }

    public static void main(String[] args)
    {

        int[][] mat = { { 0, 1, 1, 0 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 0, 0 } };

        GFG obj = new GFG();

        System.out.println(obj.maxArea(mat));
    }
}
Python
def maxArea(mat):
    n = len(mat)
    m = len(mat[0])
    res = 0

    # Choose the top-left corner.
    for top in range(n):
        for left in range(m):
            # Choose the bottom-right corner.
            for bottom in range(top, n):
                for right in range(left, m):
                    valid = True
                    # Check whether all cells inside
                    # the rectangle are 1.
                    for i in range(top, bottom + 1):
                        for j in range(left, right + 1):
                            if mat[i][j] == 0:
                                valid = False
                                break
                        if not valid:
                            break
                    # Update the maximum area if the rectangle
                    # contains only 1's.
                    if valid:
                        area = (bottom - top + 1) * (right - left + 1)
                        res = max(res, area)
    return res


if __name__ == "__main__":
    mat = [[0, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 0, 0]]
    print(maxArea(mat))
C#
using System;

public class GFG {
    // Function to find the maximum rectangle area.
    public int maxArea(int[][] mat)
    {
        int n = mat.Length;
        int m = mat[0].Length;

        int res = 0;

        // Choose the top-left corner.
        for (int top = 0; top < n; top++) {
            for (int left = 0; left < m; left++) {
                // Choose the bottom-right corner.
                for (int bottom = top; bottom < n;
                     bottom++) {
                    for (int right = left; right < m;
                         right++) {
                        bool valid = true;

                        // Check whether all cells inside
                        // the rectangle are 1.
                        for (int i = top;
                             i <= bottom && valid; i++) {
                            for (int j = left; j <= right;
                                 j++) {
                                if (mat[i][j] == 0) {
                                    valid = false;
                                    break;
                                }
                            }
                        }

                        // Update the maximum area if the
                        // rectangle contains only 1's.
                        if (valid) {
                            int area = (bottom - top + 1)
                                       * (right - left + 1);
                            res = Math.Max(res, area);
                        }
                    }
                }
            }
        }

        return res;
    }

    public static void Main()
    {
        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 } };

        GFG obj = new GFG();

        Console.WriteLine(obj.maxArea(mat));
    }
}
JavaScript
function maxArea(mat)
{
    const n = mat.length;
    const m = mat[0].length;
    let res = 0;

    // Choose the top-left corner.
    for (let top = 0; top < n; top++) {
        for (let left = 0; left < m; left++) {

            // Choose the bottom-right corner.
            for (let bottom = top; bottom < n; bottom++) {
                for (let right = left; right < m; right++) {

                    let valid = true;

                    // Check whether all cells inside
                    // the rectangle are 1.
                    for (let i = top; i <= bottom && valid;
                         i++) {
                        for (let j = left; j <= right;
                             j++) {
                            if (mat[i][j] === 0) {
                                valid = false;
                                break;
                            }
                        }
                    }

                    // Update the maximum area if the
                    // rectangle contains only 1's.
                    if (valid) {
                        const area = (bottom - top + 1)
                                     * (right - left + 1);
                        res = Math.max(res, area);
                    }
                }
            }
        }
    }

    return res;
}

// Driver Code
const mat = [
    [ 0, 1, 1, 0 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ],
    [ 1, 1, 0, 0 ]
];
console.log(maxArea(mat));

Output
8

[Better Approach] Using Dynamic Programming - O((n ^ 2) * m) Time and O(n * m) Space

The idea is to store, for each cell (i, j), the width of consecutive 1’s ending at that position in a 2D array. Then, for every cell (i, j) with value 1, iterate upwards row by row. While moving upward, keep track of the minimum width of 1’s seen so far in that column. This ensures the rectangle formed remains valid. At each step, the rectangle area is computed as: (area = minWidth * height).

Working of Approach:

  • Build a DP table memo[][], where memo[i][j] stores the width of consecutive 1s ending at cell (i, j).
  • Traverse each cell containing 1 and treat it as the bottom-right corner of a rectangle.
  • Move upwards row by row while maintaining the minimum width encountered so far.
  • Compute the rectangle area for every possible height and update the maximum area.
  • Return the maximum area after processing all cells.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int maxArea(vector<vector<int>> &mat)
{
    int n = mat.size(), m = mat[0].size();

    // memo[i][j] stores the width of consecutive 1's
    // ending at position (i, j).
    vector<vector<int>> memo(n, vector<int>(m, 0));
    int res = 0;

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

            // Compute width of 1's at (i, j).
            memo[i][j] = (j == 0) ? 1 : memo[i][j - 1] + 1;

            int width = memo[i][j];

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

    return res;
}

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
import java.util.*;

class GFG {

    public int maxArea(int[][] mat)
    {

        int n = mat.length, m = mat[0].length;

        // memo[i][j] stores the width of consecutive 1's
        // ending at position (i, j).
        int[][] memo = new int[n][m];
        int res = 0;

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

                // Compute width of 1's at (i, j).
                memo[i][j]
                    = (j == 0) ? 1 : memo[i][j - 1] + 1;

                int width = memo[i][j];

                // Traverse upwards row by row,
                // update 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);
                    res = Math.max(res, area);
                }
            }
        }

        return res;
    }

    public static void main(String[] args)
    {

        int[][] mat = { { 0, 1, 1, 0 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 0, 0 } };

        GFG obj = new GFG();

        System.out.println(obj.maxArea(mat));
    }
}
Python
def maxArea(mat):
    n = len(mat)
    m = len(mat[0])

    # memo[i][j] stores the width of consecutive 1's
    # ending at position (i, j).
    memo = [[0] * m for _ in range(n)]
    res = 0

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

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

            width = memo[i][j]

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

    return res


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

    print(maxArea(mat))
C#
using System;

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

        // memo[i][j] stores the width of consecutive 1's
        // ending at position (i, j).
        int[][] memo = new int[n][];
        for (int i = 0; i < n; i++)
            memo[i] = new int[m];

        int res = 0;

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

                // Compute width of 1's at (i, j).
                memo[i][j]
                    = (j == 0) ? 1 : memo[i][j - 1] + 1;

                int width = memo[i][j];

                // Traverse upwards row by row,
                // update 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);
                    res = Math.Max(res, area);
                }
            }
        }

        return res;
    }

    public static void Main()
    {
        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 } };

        GFG obj = new GFG();

        Console.WriteLine(obj.maxArea(mat));
    }
}
JavaScript
function maxArea(mat)
{
    let n = mat.length, m = mat[0].length;

    // memo[i][j] stores the width of consecutive 1's
    // ending at position (i, j).
    let memo
        = Array.from({length : n}, () => Array(m).fill(0));
    let res = 0;

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

            // Compute width of 1's at (i, j).
            memo[i][j] = (j === 0) ? 1 : memo[i][j - 1] + 1;

            let width = memo[i][j];

            // Traverse upwards row by row,
            // update 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);
                res = Math.max(res, area);
            }
        }
    }

    return res;
}

// Driver Code
let mat = [
    [ 0, 1, 1, 0 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ],
    [ 1, 1, 0, 0 ]
];

console.log(maxArea(mat));

Output
8

[Expected Approach] Using Largest Rectangular Area in a Histogram - O(n * m) Time and O(m) Space

The idea is to treat each row as the base of a histogram by maintaining the heights of consecutive 1s in every column. Then, the known stack-based Largest Rectangle in Histogram algorithm gives the maximum area for that row. Repeat this for all rows and return the maximum area obtained.

Working of Approach:

  • Maintain a histogram array where each element stores the number of consecutive 1s in that column up to the current row.
  • Traverse the matrix row by row and update the histogram by increasing the height for 1 and resetting it to 0 for 0.
  • For every updated histogram, use a monotonic increasing stack to find the largest rectangle in linear time.
  • The stack helps determine the maximum width for every bar by finding its previous and next smaller elements.
  • Update the maximum rectangle area for each row and return the overall maximum.

Let us understand with an example:
Input: mat[][] = [[0, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 0, 0]]

  • Row 0: Histogram = [0, 1, 1, 0], largest rectangle area = 2.
  • Row 1: Histogram = [1, 2, 2, 1], largest rectangle area = 4.
  • Row 2: Histogram = [2, 3, 3, 2], largest rectangle area = 8.
  • Row 3: Histogram = [3, 4, 0, 0], largest rectangle area = 6.
2056958495

Therefore, the maximum rectangle consisting of only 1s has area 8.

C++
#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
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 res = 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;
            }
        }

        res = max(res, getMaxArea(arr));
    }

    return res;
}

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
import java.util.*;

class GFG {

    // Function to find the maximum area of
    // rectangle in a histogram.
    public 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.
    public 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 res = 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;
                }
            }

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

        return res;
    }

    public static void main(String[] args)
    {

        int[][] mat = { { 0, 1, 1, 0 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 1, 1 },
                        { 1, 1, 0, 0 } };

        GFG obj = new GFG();

        System.out.println(obj.maxArea(mat));
    }
}
Python
from typing import List

# Function to find the maximum area of
# rectangle in a histogram.


def getMaxArea(arr: List[int]) -> int:
    n = len(arr)
    s = []
    res = 0
    tp, curr = 0, 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: List[List[int]]) -> int:
    n = len(mat)
    m = len(mat[0])

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

    res = 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

        res = max(res, getMaxArea(arr))

    return res


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

    print(maxArea(mat))
C#
using System;
using System.Collections.Generic;

public 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;
        int 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.
    public 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 res = 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;
                }
            }

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

        return res;
    }

    public static void Main()
    {
        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 } };

        GFG obj = new GFG();

        Console.WriteLine(obj.maxArea(mat));
    }
}
JavaScript
function getMaxArea(arr)
{
    let n = arr.length;
    let s = [];
    let res = 0;
    let tp, curr;
    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
            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) {
        tp = s.pop();
        curr = arr[tp]
               * (s.length === 0 ? n
                                 : n - s[s.length - 1] - 1);
        res = Math.max(res, curr);
    }

    return res;
}

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 res = 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;
            }
        }

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

    return res;
}

// Driver Code
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:

Comment