Code Logo

Maximal Rectangle

Published at23 Jul 2026
Hard 2 views
Like0

You are given a 2D binary matrix. Find the area of the largest rectangle containing only 1s.

This builds on the Largest Rectangle in Histogram algorithm. Treat each row as a base: compute heights of consecutive 1s ending at each cell. For each row, apply the histogram algorithm to find the max rectangle for that row. The overall max is the answer. Heights update per row: if cell is 1, add 1; if 0, reset to 0. Then run the monotonic stack histogram algorithm. Time O(n*m).

The key insight is that each row can be treated as a histogram. By applying the histogram algorithm to each row's heights, you find the maximum rectangle ending at that row. The global max across all rows is the answer.

This problem extends the Largest Rectangle in Histogram to two dimensions. The observation is that each row can be treated as a base of a histogram, where the height of each bar is the number of consecutive 1s ending at that cell in the current row. By iterating through the rows and updating the heights, you can apply the histogram algorithm at each row to find the maximum rectangle that ends at that row.

The time complexity is O(rows * cols) because each row runs the linear histogram algorithm. The space complexity is O(cols) for the heights array. This is optimal since you must examine each cell at least once.

To build the heights array, iterate through each row. For each cell, if it contains '1', add 1 to the previous height at that column; if '0', reset the height to 0. Then run the histogram algorithm on the current heights array. The histogram algorithm uses a monotonic increasing stack: when a shorter bar is encountered, it pops taller bars and calculates their area using the current index as right boundary and the new top of stack as left boundary. The overall maximum across all rows is the final answer.

A common optimization is to append a 0 to the heights array before running the histogram algorithm, which forces all remaining bars to be processed without needing special handling after the loop. This simplifies the code and avoids edge cases with the last bar.

Example Input & Output

Example 1
Input
["0"]
Output
0
Explanation

No 1s.

Example 2
Input
["10100","10111","11111","10010"]
Output
6
Explanation

Max rectangle area 6.

Example 3
Input
["1"]
Output
1
Explanation

Single 1.

Algorithm Flow

Recommendation Algorithm Flow for Maximal Rectangle
Recommendation Algorithm Flow for Maximal Rectangle

Solution Approach

For each row, update heights. Run histogram algorithm. Track max.

function solution(matrix) {
  if (!matrix.length) return 0;
  var h = new Array(matrix[0].length).fill(0), maxA = 0;
  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < matrix[0].length; j++)
      h[j] = matrix[i][j] === "1" ? h[j] + 1 : 0;
    maxA = Math.max(maxA, largest(h));
  }
  return maxA;
  function largest(h) {
    var s = [], m = 0;
    for (var k = 0; k <= h.length; k++) {
      var ch = k < h.length ? h[k] : 0;
      while (s.length && ch < h[s[s.length-1]]) {
        var ht = h[s.pop()];
        var w = s.length ? k - s[s.length-1] - 1 : k;
        m = Math.max(m, ht * w);
      }
      s.push(k);
    }
    return m;
  }
}

O(n*m) time, O(m) space.

Best Answers

java
import java.util.*;
class Solution {
    public int solution(String[] matrix) {
        if (matrix.length == 0) return 0;
        int[] h = new int[matrix[0].length()];
        int maxA = 0;
        for (String row : matrix) {
            for (int j = 0; j < row.length(); j++)
                h[j] = row.charAt(j) == '1' ? h[j] + 1 : 0;
            maxA = Math.max(maxA, largest(h));
        }
        return maxA;
    }
    int largest(int[] h) {
        Stack<Integer> s = new Stack<>();
        int m = 0;
        for (int i = 0; i <= h.length; i++) {
            int ch = i < h.length ? h[i] : 0;
            while (!s.isEmpty() && ch < h[s.peek()]) {
                int ht = h[s.pop()];
                int w = s.isEmpty() ? i : i - s.peek() - 1;
                m = Math.max(m, ht * w);
            }
            s.push(i);
        }
        return m;
    }
}