Maximal Rectangle In C,CPP,JAVA,PYTHON,C#,JS

Spread the love
Close-up of HTML code highlighted in vibrant colors on a computer monitor.

Maximal Rectangle Problem

The “Maximal Rectangle” problem is a classical algorithmic challenge where you are given a 2D binary matrix filled with 0‘s and 1‘s. The goal is to find the largest rectangle containing only 1‘s and return its area.

Problem Statement:

Given a binary matrix, find the area of the largest rectangle containing only 1s.

Example:

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 the rectangle with the bottom-right corner at matrix[2][2], spanning 3 columns and 2 rows. Therefore, the area is 3 * 2 = 6.


Approach:

  1. Transform the Problem: Each row in the matrix can be treated as the base of a histogram where the heights of the bars are the number of consecutive 1s up to that row.
  2. Dynamic Programming (DP) + Histogram:
    • Convert the 2D matrix into a histogram where the height of each column increases as you move down the rows if the cell is 1.
    • For each row, calculate the largest rectangle possible in the histogram formed by the heights of the bars up to that row.
  3. Find Max Area in Histogram:
    • For each row, use a stack-based approach to calculate the largest rectangle in a histogram in O(m) time where m is the number of columns.
  4. Time Complexity:
    • Building the histogram takes O(n * m) where n is the number of rows and m is the number of columns.
    • The stack-based approach to find the maximal rectangle in the histogram also runs in O(m) for each row.
    • Overall time complexity is O(n * m).
  5. Space Complexity: O(m) where m is the number of columns for storing the heights.

Algorithm:

  1. Convert each row to a histogram by updating heights (based on whether the current cell is 1 or 0).
  2. For each row, compute the maximum rectangle area using a stack-based method to calculate the largest rectangle in the histogram.
  3. Update the result for the maximum area.

Code Implementation in Different Languages:

C:

#include <stdio.h>
#include <stdlib.h>

int maxHistArea(int *hist, int m) {
int *stack = (int *)malloc(m * sizeof(int));
int top = -1, maxArea = 0, area = 0, i = 0;

while (i < m) {
if (top == -1 || hist[stack[top]] <= hist[i]) {
stack[++top] = i++;
} else {
int height = hist[stack[top--]];
int width = (top == -1) ? i : i - stack[top] - 1;
area = height * width;
maxArea = (maxArea > area) ? maxArea : area;
}
}
while (top >= 0) {
int height = hist[stack[top--]];
int width = (top == -1) ? i : i - stack[top] - 1;
area = height * width;
maxArea = (maxArea > area) ? maxArea : area;
}
free(stack);
return maxArea;
}

int maximalRectangle(char **matrix, int n, int m) {
int *heights = (int *)calloc(m, sizeof(int));
int maxArea = 0;

for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
heights[j] = (matrix[i][j] == '1') ? heights[j] + 1 : 0;
}
int area = maxHistArea(heights, m);
maxArea = (maxArea > area) ? maxArea : area;
}
free(heights);
return maxArea;
}

int main() {
char *matrix[] = {
"10100",
"10111",
"11111",
"10010"
};
int n = 4, m = 5;
printf("Maximal Rectangle Area: %d\n", maximalRectangle(matrix, n, m));
return 0;
}

C++:

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

int maxHistArea(vector<int>& hist, int m) {
stack<int> st;
int maxArea = 0, area = 0, i = 0;

while (i < m) {
if (st.empty() || hist[st.top()] <= hist[i]) {
st.push(i++);
} else {
int height = hist[st.top()];
st.pop();
int width = st.empty() ? i : i - st.top() - 1;
area = height * width;
maxArea = max(maxArea, area);
}
}
while (!st.empty()) {
int height = hist[st.top()];
st.pop();
int width = st.empty() ? i : i - st.top() - 1;
area = height * width;
maxArea = max(maxArea, area);
}
return maxArea;
}

int maximalRectangle(vector<vector<char>>& matrix) {
if (matrix.empty()) return 0;

int n = matrix.size(), m = matrix[0].size();
vector<int> heights(m, 0);
int maxArea = 0;

for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
heights[j] = (matrix[i][j] == '1') ? heights[j] + 1 : 0;
}
maxArea = max(maxArea, maxHistArea(heights, m));
}
return maxArea;
}

int main() {
vector<vector<char>> matrix = {
{'1', '0', '1', '0', '0'},
{'1', '0', '1', '1', '1'},
{'1', '1', '1', '1', '1'},
{'1', '0', '0', '1', '0'}
};
cout << "Maximal Rectangle Area: " << maximalRectangle(matrix) << endl;
return 0;
}

Java:

import java.util.Stack;

public class MaximalRectangle {
public static int maxHistArea(int[] hist, int m) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0, area = 0, i = 0;

while (i < m) {
if (stack.isEmpty() || hist[stack.peek()] <= hist[i]) {
stack.push(i++);
} else {
int height = hist[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
area = height * width;
maxArea = Math.max(maxArea, area);
}
}
while (!stack.isEmpty()) {
int height = hist[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
area = height * width;
maxArea = Math.max(maxArea, area);
}
return maxArea;
}

public static int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) return 0;

int n = matrix.length, m = matrix[0].length;
int[] heights = new int[m];
int maxArea = 0;

for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
heights[j] = (matrix[i][j] == '1') ? heights[j] + 1 : 0;
}
maxArea = Math.max(maxArea, maxHistArea(heights, m));
}
return maxArea;
}

public static void main(String[] args) {
char[][] matrix = {
{'1', '0', '1', '0', '0'},
{'1', '0', '1', '1', '1'},
{'1', '1', '1', '1', '1'},
{'1', '0', '0', '1', '0'}
};
System.out.println("Maximal Rectangle Area: " + maximalRectangle(matrix));
}
}

Python:

def maxHistArea(heights):
stack = []
max_area = 0
i = 0
while i < len(heights):
if not stack or heights[stack[-1]] <= heights[i]:
stack.append(i)
i += 1
else:
h = heights[stack.pop()]
w = i if not stack else i - stack[-1] - 1
max_area = max(max_area, h * w)

while stack:
h = heights[stack.pop()]
w = i if not stack else i - stack[-1] - 1
max_area = max(max_area, h * w)

return max_area

def maximalRectangle(matrix):
if not matrix:
return 0

n, m = len(matrix), len(matrix[0])
heights = [0] * m
max_area = 0

for i in range(n):
for j in range(m):
heights[j] = heights[j] + 1 if matrix[i][j] == '1' else 0
max_area = max(max_area, maxHistArea(heights))

return max_area

# Example Usage
matrix = [
['1', '0', '1', '0', '0'],
['1', '0', '1', '1', '1'],
['1', '1', '1', '1', '1'],
['1', '0', '0', '1', '0']
]
print("Maximal Rectangle Area:", maximalRectangle(matrix))

C#:

using System;
using System.Collections.Generic;

public class MaximalRectangle {
public static int MaxHistArea(int[] hist, int m) {
Stack<int> stack = new Stack<int>();
int maxArea = 0, area = 0, i = 0;

while (i < m) {
if (stack.Count == 0 || hist[stack.Peek()] <= hist[i]) {
stack.Push(i++);
} else {
int height = hist[stack.Pop()];
int width = stack.Count == 0 ? i : i - stack.Peek() - 1;
area = height * width;
maxArea = Math.Max(maxArea, area);
}
}
while (stack.Count > 0) {
int height = hist[stack.Pop()];
int width = stack.Count == 0 ? i : i - stack.Peek() - 1;
area = height * width;
maxArea = Math.Max(maxArea, area);
}
return maxArea;
}

public static int MaximalRectangle(char[][] matrix) {
if (matrix.Length == 0) return 0;

int n = matrix.Length, m = matrix[0].Length;
int[] heights = new int[m];
int maxArea = 0;

for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
heights[j] = (matrix[i][j] == '1') ? heights[j] + 1 : 0;
}
maxArea = Math.Max(maxArea, MaxHistArea(heights, m));
}
return maxArea;
}

public static void Main() {
char[][] matrix = {
new char[] {'1', '0', '1', '0', '0'},
new char[] {'1', '0', '1', '1', '1'},
new char[] {'1', '1', '1', '1', '1'},
new char[] {'1', '0', '0', '1', '0'}
};
Console.WriteLine("Maximal Rectangle Area: " + MaximalRectangle(matrix));
}
}

JavaScript:

function maxHistArea(heights) {
let stack = [];
let maxArea = 0, area = 0, i = 0;

while (i < heights.length) {
if (stack.length === 0 || heights[stack[stack.length - 1]] <= heights[i]) {
stack.push(i++);
} else {
let h = heights[stack.pop()];
let w = stack.length === 0 ? i : i - stack[stack.length - 1] - 1;
maxArea = Math.max(maxArea, h * w);
}
}

while (stack.length > 0) {
let h = heights[stack.pop()];
let w = stack.length === 0 ? i : i - stack[stack.length - 1] - 1;
maxArea = Math.max(maxArea, h * w);
}

return maxArea;
}

function maximalRectangle(matrix) {
if (!matrix.length) return 0;

let n = matrix.length, m = matrix[0].length;
let heights = new Array(m).fill(0);
let maxArea = 0;

for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
heights[j] = (matrix[i][j] === '1') ? heights[j] + 1 : 0;
}
maxArea = Math.max(maxArea, maxHistArea(heights));
}
return maxArea;
}

// Example Usage
let matrix = [
['1', '0', '1', '0', '0'],
['1', '0', '1', '1', '1'],
['1', '1', '1', '1', '1'],
['1', '0', '0', '1', '0']
];

console.log("Maximal Rectangle Area:", maximalRectangle(matrix));

Summary:

  1. Time Complexity: O(n * m), where n is the number of rows and m is the number of columns.
  2. Space Complexity: O(m), where m is the number of columns (for storing heights).