Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximal Rectangle #1633

Merged
merged 12 commits into from
Nov 4, 2024
54 changes: 54 additions & 0 deletions Dynamic Programming/Maximal Rectangle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Problem Overview
The task is to find the largest rectangle containing only 1's in a given binary matrix. Each element in the matrix is either '0' or '1', and we want to calculate the maximum area of contiguous '1's that can form a rectangle.

Approach
The problem can be approached using the concept of dynamic histogram heights, where each row of the matrix is treated as a base and we calculate the histogram height of each column based on the presence of '1's in the rows above it. This allows us to use techniques similar to finding the largest rectangle in a histogram for each row, which can be efficiently solved with the following steps.

Steps to Solve
Initialize Arrays:

heights[]: Stores the height of '1's for each column. At any row i, if matrix[i][j] is '1', the height at heights[j] is incremented; otherwise, it's reset to 0.
leftBoundaries[]: Tracks the left boundary (leftmost column where '1's can extend) for each column in the current row.
rightBoundaries[]: Tracks the right boundary (rightmost column where '1's can extend) for each column in the current row.
Row-by-Row Processing:

For each row, update the heights[], leftBoundaries[], and rightBoundaries[] arrays.
Calculate the maximum area for each rectangle ending at each column by multiplying the height by the width defined by the difference between the right and left boundaries.
Calculate Maximum Rectangle Area:

For each column, calculate the rectangle area using the formula area = height * (rightBoundary - leftBoundary).
Update maxRectangle with the maximum area encountered.
Helper Functions
updateHeightsAndLeftBoundaries: Updates the heights[] array and leftBoundaries[] for the current row. If matrix[i][j] is '1', heights[j] is incremented, and leftBoundaries[j] is updated based on the current left boundary. Otherwise, heights[j] is reset to 0, and the left boundary is updated.

updateRightBoundaries: Updates the rightBoundaries[] array for the current row. If matrix[i][j] is '1', rightBoundaries[j] is updated based on the current right boundary. If not, rightBoundaries[j] is reset, and right is adjusted.

calculateMaxRectangle: Iterates over each column and calculates the area for each possible rectangle using heights, leftBoundaries, and rightBoundaries. It then updates maxRectangle if a larger area is found.

Complexity Analysis
Time Complexity:
𝑂
(
𝑚
×
𝑛
)
O(m×n), where
𝑚
m is the number of rows and
𝑛
n is the number of columns. Each cell is processed once, and boundary updates are linear.
Space Complexity:
𝑂
(
𝑛
)
O(n), for storing heights, leftBoundaries, and rightBoundaries.
Summary
This approach leverages a dynamic programming technique to keep track of heights and boundaries, transforming the problem into a maximal rectangle calculation on each row as if it were a histogram. By iteratively updating the boundaries and heights, we efficiently compute the maximal rectangle area in a binary matrix. This method ensures that the solution is optimal for large matrices while maintaining manageable space complexity.






71 changes: 71 additions & 0 deletions Dynamic Programming/Maximal Rectangle/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) {
if (matrix == NULL || matrixSize == 0 || matrixColSize[0] == 0) {
return 0;
}

int m = matrixSize;
int n = matrixColSize[0];

int* heights = (int*)calloc(n, sizeof(int));
int* leftBoundaries = (int*)calloc(n, sizeof(int));
int* rightBoundaries = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
rightBoundaries[i] = n;
}

int maxRectangle = 0;

for (int i = 0; i < m; i++) {
int left = 0;
int right = n;

updateHeightsAndLeftBoundaries(matrix[i], heights, leftBoundaries, n, &left);

updateRightBoundaries(matrix[i], rightBoundaries, n, &right);

maxRectangle = calculateMaxRectangle(heights, leftBoundaries, rightBoundaries, n, maxRectangle);
}

free(heights);
free(leftBoundaries);
free(rightBoundaries);

return maxRectangle;
}

void updateHeightsAndLeftBoundaries(char* row, int* heights, int* leftBoundaries, int n, int* left) {
for (int j = 0; j < n; j++) {
if (row[j] == '1') {
heights[j]++;
leftBoundaries[j] = leftBoundaries[j] > *left ? leftBoundaries[j] : *left;
} else {
heights[j] = 0;
leftBoundaries[j] = 0;
*left = j + 1;
}
}
}

void updateRightBoundaries(char* row, int* rightBoundaries, int n, int* right) {
for (int j = n - 1; j >= 0; j--) {
if (row[j] == '1') {
rightBoundaries[j] = rightBoundaries[j] < *right ? rightBoundaries[j] : *right;
} else {
rightBoundaries[j] = n;
*right = j;
}
}
}

int calculateMaxRectangle(int* heights, int* leftBoundaries, int* rightBoundaries, int n, int maxRectangle) {
for (int j = 0; j < n; j++) {
int width = rightBoundaries[j] - leftBoundaries[j];
int area = heights[j] * width;
maxRectangle = maxRectangle > area ? maxRectangle : area;
}
return maxRectangle;
}
50 changes: 0 additions & 50 deletions Dynamic Programming/Minimum Cost to Cut a Stick/program.c

This file was deleted.

64 changes: 0 additions & 64 deletions Dynamic Programming/Minimum Cost to Cut a Stick/readme

This file was deleted.

99 changes: 0 additions & 99 deletions Graph Algorithms/Swim in Rising Water/program.c

This file was deleted.

Loading