GfG QA is closing soon... Please refer PRACTICE or GfG now on wards !!

Find the largest rectangle containing all ones and return its area.

Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing all ones and return its area.

Bonus if you can solve it in O(n^2) or less.

Example :

A : [  1 1 1
       0 1 1
       1 0 0 
    ]

Output : 4 

As the max area rectangle is created by the 2x2 rectangle created by (0,1), (0,2), (1,1) and 
asked Oct 13, 2015 by Swanky
retagged Oct 13, 2015 by Swanky

2 Answers

The bruteforce approach is to look at all pairs of (i,j) to (k,l) and check if its filled with 1s. This approach however is O(NNNNN^2) = O(N^6). [ N^4 ways to choose i,j,k,l and then N^2 elements in the square ]. 
We can optimize this approach if we had additional space to store results for your previous calculations. Maybe if we knew the result for (i, j) to (k, l - 1) or (i, j) to (k - 1, l) or both.

We can improve from N^6 by storing in dp[i][j][k][l] if (i,j) to (k,l) is all filled with 1. 
dp[i][j[k][l] = 1 iff dp[i][j][k][l-1] = 1 && dp[i][j][k-1][l] = 1 and matrix[k][l] = 1.

Now we can improve this further. What if with every (i,j) we stored the length of 1s in the same row i starting from (i,j). 
We can move down in the column j from row i and determine the largest rectangle without having to visit all cells. 
 

Even Better Solution :
Lets dp[i][j] denote the length of 1s in the same row i starting from (i,j).

So our current max with one end of the rectangle at (i,j) would be dp[i][j]. 
As we move to the next column, there are 2 cases : 
1) dp[i+1][j] >= dp[i][j] which means that we can take dp[i][j] 1s from next column as well and extend our current rectangle as it is, with one more extra row.
11100000 - 111
11111100 - 111

2) dp[i+1][j] < dp[i][j] which means that if we want to extend our current rectangle to next row, we need to reduce the number of columns in it to dp[i+1][j]
11100000 - 11 
11000000 - 11

As mentioned above, we keep increasing the columns and adjusting the width of the rectangle. 
O(N^3) time complexity.

Even though N^3 is acceptable, it might be worth exploring a better solution. 
If we notice, laying out dp[i][j] helps us make histograms in every row. Then the problem becomes of finding the maximum area in histograms which can be done in O(n). This would lead to an O(N^2) solution. However, I am posting here is O(N^3) .

 

// Author :: Gaurav Ahirwar
#include<bits/stdc++.h>
#define R 3
#define C 3
using namespace std;

int solve(char matrix[][C]) {

    int rows = R;
    if (rows == 0) return 0;
    
	int cols = C;
    if (cols == 0) return 0;
    
    int dp[rows][cols]; 
	memset(dp, 0, sizeof dp);
    int area = 0;

    for (int i = 0; i < rows; i++) { 
        for (int j = 0; j < cols; j++) {

            if (matrix[i][j] == '1') { 

                if (j == 0) dp[i][j] = 1;
                else dp[i][j] = dp[i][j - 1] + 1;

                int y = 1;
                int x = cols;

                while((i - y + 1 >= 0) && (matrix[i - y + 1][j] == '1')) {

                    x = min(x, dp[i - y + 1][j]);
                    area = max(area, x * y);
                    y++;
                } 
            }
        }
    }

    return area;
}

int main() {
	
	char matrix[][C] = {{'1', '1', '1'}, 
	                   {'0', '1', '1'}, 
					   {'1', '0', '0'}};
	
	cout << solve(matrix) << endl;
	return 0;
}

 

answered Oct 13, 2015 by Mr.Lazy
...