HomeLeetcode85. Maximal Rectangle - Leetcode Solutions

85. Maximal Rectangle – Leetcode Solutions

Description:

Given a rows x cols binary matrix filled with 0‘s and 1‘s, find the largest rectangle containing only 1‘s and return its area.

Examples:

Example 1:

Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.

Example 2:

Input: matrix = [["0"]]
Output: 0

Example 3:

Input: matrix = [["1"]]
Output: 1

Solution in Python:

To solve the problem of finding the largest rectangle containing only 1’s in a binary matrix, we can use a dynamic programming approach combined with the largest rectangle in histogram algorithm.

Python
from typing import List

class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        if not matrix or not matrix[0]:
            return 0

        # Initialize the dimensions of the matrix
        rows, cols = len(matrix), len(matrix[0])
        # Initialize the height array
        heights = [0] * cols
        # Variable to store the maximum area
        max_area = 0

        # Iterate over each row in the matrix
        for row in matrix:
            for j in range(cols):
                # Update the height array
                if row[j] == '1':
                    heights[j] += 1
                else:
                    heights[j] = 0
            
            # Update the maximum area using the largest rectangle in histogram method
            max_area = max(max_area, self.largestRectangleArea(heights))

        return max_area

    def largestRectangleArea(self, heights: List[int]) -> int:
        # Stack to store the indices of the histogram bars
        stack = []
        # Variable to store the maximum area
        max_area = 0
        # Append a zero height to ensure we process all elements in the stack by the end
        heights.append(0)
        
        # Iterate over each height in the histogram
        for i in range(len(heights)):
            # While the current bar is shorter than the last one in the stack
            while stack and heights[i] < heights[stack[-1]]:
                # Pop the height from the stack
                h = heights[stack.pop()]
                # Calculate the width as the distance between the current index and the index
                # of the new top of the stack, minus one (if stack is not empty, else i)
                w = i if not stack else i - stack[-1] - 1
                # Update the maximum area
                max_area = max(max_area, h * w)
            # Push the current index onto the stack
            stack.append(i)
        
        # Remove the appended zero
        heights.pop()
        
        return max_area

Explanation:

  1. Edge Case Handling:
    • Check if the matrix or the first row is empty. If either is empty, return 0 as there’s no rectangle possible.
  2. Height Array Initialization:
    • Initialize a heights array with the same number of columns as the matrix, filled with 0’s. This array will be used to store the heights of histogram bars for each column.
  3. Row-wise Histogram Update:
    • Iterate over each row in the matrix. For each element in the row, update the corresponding value in the heights array:
      • If the element is ‘1’, increase the height by 1.
      • If the element is ‘0’, reset the height to 0.
  4. Calculate Maximum Area for Each Row:
    • After updating the heights array for the current row, call the largestRectangleArea method to calculate the maximum rectangular area for the current histogram.
    • Update the max_area variable with the maximum value returned from this method.
  5. Largest Rectangle in Histogram Calculation:
    • This method uses a stack-based approach to find the largest rectangle in a histogram, similar to the solution explained previously for the largest rectangle problem in a histogram.
  6. Stack-based Calculation:
    • Use a stack to store the indices of the histogram bars.
    • Iterate over the heights array. For each height, if the current height is less than the height of the bar at the index stored at the stack’s top, calculate the area of the rectangle ending at the bar corresponding to the top index of the stack.
    • Update the maximum area accordingly.
    • Push the current index onto the stack.

By combining these approaches, we can efficiently calculate the largest rectangle containing only 1’s in the given binary matrix.

Solution in Javascript:

JavaScript
/**
 * @param {character[][]} matrix
 * @return {number}
 */
var maximalRectangle = function(matrix) {
    if (!matrix || matrix.length === 0 || matrix[0].length === 0) {
        return 0;
    }

    // Initialize the dimensions of the matrix
    const rows = matrix.length;
    const cols = matrix[0].length;
    // Initialize the height array
    const heights = new Array(cols).fill(0);
    // Variable to store the maximum area
    let maxArea = 0;

    // Iterate over each row in the matrix
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < cols; j++) {
            // Update the height array
            if (matrix[i][j] === '1') {
                heights[j] += 1;
            } else {
                heights[j] = 0;
            }
        }
        // Update the maximum area using the largest rectangle in histogram method
        maxArea = Math.max(maxArea, largestRectangleArea(heights));
    }

    return maxArea;
};

/**
 * @param {number[]} heights
 * @return {number}
 */
var largestRectangleArea = function(heights) {
    // Stack to store the indices of the histogram bars
    const stack = [];
    // Variable to store the maximum area
    let maxArea = 0;
    // Append a zero height to ensure we process all elements in the stack by the end
    heights.push(0);

    // Iterate over each height in the histogram
    for (let i = 0; i < heights.length; i++) {
        // While the current bar is shorter than the last one in the stack
        while (stack.length > 0 && heights[i] < heights[stack[stack.length - 1]]) {
            // Pop the height from the stack
            const h = heights[stack.pop()];
            // Calculate the width as the distance between the current index and the index
            // of the new top of the stack, minus one (if stack is not empty, else i)
            const w = stack.length === 0 ? i : i - stack[stack.length - 1] - 1;
            // Update the maximum area
            maxArea = Math.max(maxArea, h * w);
        }
        // Push the current index onto the stack
        stack.push(i);
    }

    // Remove the appended zero
    heights.pop();

    return maxArea;
};

Solution in Java:

Java
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }

        // Initialize the dimensions of the matrix
        int rows = matrix.length;
        int cols = matrix[0].length;
        // Initialize the height array
        int[] heights = new int[cols];
        // Variable to store the maximum area
        int maxArea = 0;

        // Iterate over each row in the matrix
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // Update the height array
                if (matrix[i][j] == '1') {
                    heights[j] += 1;
                } else {
                    heights[j] = 0;
                }
            }
            // Update the maximum area using the largest rectangle in histogram method
            maxArea = Math.max(maxArea, largestRectangleArea(heights));
        }

        return maxArea;
    }

    private int largestRectangleArea(int[] heights) {
        // Stack to store the indices of the histogram bars
        Stack<Integer> stack = new Stack<>();
        // Variable to store the maximum area
        int maxArea = 0;
        // Append a zero height to ensure we process all elements in the stack by the end
        int[] extendedHeights = Arrays.copyOf(heights, heights.length + 1);

        // Iterate over each height in the histogram
        for (int i = 0; i < extendedHeights.length; i++) {
            // While the current bar is shorter than the last one in the stack
            while (!stack.isEmpty() && extendedHeights[i] < extendedHeights[stack.peek()]) {
                // Pop the height from the stack
                int h = extendedHeights[stack.pop()];
                // Calculate the width as the distance between the current index and the index
                // of the new top of the stack, minus one (if stack is not empty, else i)
                int w = stack.isEmpty() ? i : i - stack.peek() - 1;
                // Update the maximum area
                maxArea = Math.max(maxArea, h * w);
            }
            // Push the current index onto the stack
            stack.push(i);
        }

        return maxArea;
    }
}

Solution in C#:

C#
using System;
using System.Collections.Generic;

public class Solution {
    public int MaximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.Length == 0 || matrix[0].Length == 0) {
            return 0;
        }

        // Initialize the dimensions of the matrix
        int rows = matrix.Length;
        int cols = matrix[0].Length;
        // Initialize the height array
        int[] heights = new int[cols];
        // Variable to store the maximum area
        int maxArea = 0;

        // Iterate over each row in the matrix
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // Update the height array
                if (matrix[i][j] == '1') {
                    heights[j] += 1;
                } else {
                    heights[j] = 0;
                }
            }
            // Update the maximum area using the largest rectangle in histogram method
            maxArea = Math.Max(maxArea, LargestRectangleArea(heights));
        }

        return maxArea;
    }

    private int LargestRectangleArea(int[] heights) {
        // Stack to store the indices of the histogram bars
        Stack<int> stack = new Stack<int>();
        // Variable to store the maximum area
        int maxArea = 0;
        // Append a zero height to ensure we process all elements in the stack by the end
        int[] extendedHeights = new int[heights.Length + 1];
        Array.Copy(heights, extendedHeights, heights.Length);
        extendedHeights[heights.Length] = 0;

        // Iterate over each height in the histogram
        for (int i = 0; i < extendedHeights.Length; i++) {
            // While the current bar is shorter than the last one in the stack
            while (stack.Count > 0 && extendedHeights[i] < extendedHeights[stack.Peek()]) {
                // Pop the height from the stack
                int h = extendedHeights[stack.Pop()];
                // Calculate the width as the distance between the current index and the index
                // of the new top of the stack, minus one (if stack is not empty, else i)
                int w = stack.Count == 0 ? i : i - stack.Peek() - 1;
                // Update the maximum area
                maxArea = Math.Max(maxArea, h * w);
            }
            // Push the current index onto the stack
            stack.Push(i);
        }

        return maxArea;
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular