Find the largest rectangle of 1’s with swapping of columns allowed

27 Dec, 2021
Given a matrix with 0 and 1’s, find the largest rectangle of all 1’s in the matrix. The rectangle can be formed by swapping any pair of columns of given matrix.Example:  
Input: bool mat[][] = { {0, 1, 0, 1, 0},
                        {0, 1, 0, 1, 1},
                        {1, 1, 0, 1, 0}
                      };
Output: 6
The largest rectangle's area is 6. The rectangle 
can be formed by swapping column 2 with 3
The matrix after swapping will be
     0 0 1 1 0
     0 0 1 1 1
     1 0 1 1 0


Input: bool mat[R][C] = { {0, 1, 0, 1, 0},
                         {0, 1, 1, 1, 1},
                         {1, 1, 1, 0, 1},
                         {1, 1, 1, 1, 1}
                      };
Output: 9
 
The idea is to use an auxiliary matrix to store count of consecutive 1’s in every column. Once we have these counts, we sort all rows of auxiliary matrix in non-increasing order of counts. Finally traverse the sorted rows to find the maximum area. Note : After forming the auxiliary matrix each row becomes independent, hence we can swap or sort each row independently.It is because we can only swap columns, so we have made each row independent and find the max area of rectangle possible with row and column. Below are detailed steps for first example mentioned above.Step 1: First of all, calculate no. of consecutive 1’s in every column. An auxiliary array hist[][] is used to store the counts of consecutive 1’s. So for the above first example, contents of hist[R][C] would be 
    0 1 0 1 0
    0 2 0 2 1
    1 3 0 3 0
Time complexity of this step is O(R*C) Step 2: Sort the rows in non-increasing fashion. After sorting step the matrix hist[][] would be 
    1 1 0 0 0
    2 2 1 0 0
    3 3 1 0 0
This step can be done in O(R * (R + C)). Since we know that the values are in range from 0 to R, we can use counting sort for every row. The sorting is actually the swapping of columns. If we look at the 3rd row under step 2: 3 3 1 0 0 The sorted row corresponds to swapping the columns so that the column with the highest possible rectangle is placed first, after that comes the column that allows the second highest rectangle and so on. So, in the example there are 2 columns that can form a rectangle of height 3. That makes an area of 3*2=6. If we try to make the rectangle wider the height drops to 1, because there are no columns left that allow a higher rectangle on the 3rd row.Step 3: Traverse each row of hist[][] and check for the max area. Since every row is sorted by count of 1’s, current area can be calculated by multiplying column number with value in hist[i][j]. This step also takes O(R * C) time.Below is the implementation based of above idea.  
C++
Java
Python3
C#
Javascript
// C++ program to find the largest rectangle of 1's with swapping// of columns allowed.#include <bits/stdc++.h>#define R 3#define C 5 using namespace std; // Returns area of the largest rectangle of 1'sint maxArea(bool mat[R][C]){    // An auxiliary array to store count of consecutive 1's    // in every column.    int hist[R + 1][C + 1];     // Step 1: Fill the auxiliary array hist[][]    for (int i = 0; i < C; i++) {        // First row in hist[][] is copy of first row in mat[][]        hist[0][i] = mat[0][i];         // Fill remaining rows of hist[][]        for (int j = 1; j < R; j++)            hist[j][i] = (mat[j][i] == 0) ? 0 : hist[j - 1][i] + 1;    }     // Step 2: Sort columns of hist[][] in non-increasing order    for (int i = 0; i < R; i++) {        int count[R + 1] = { 0 };         // counting occurrence        for (int j = 0; j < C; j++)            count[hist[i][j]]++;         // Traverse the count array from right side        int col_no = 0;        for (int j = R; j >= 0; j--) {            if (count[j] > 0) {                for (int k = 0; k < count[j]; k++) {                    hist[i][col_no] = j;                    col_no++;                }            }        }    }     // Step 3: Traverse the sorted hist[][] to find maximum area    int curr_area, max_area = 0;    for (int i = 0; i < R; i++) {        for (int j = 0; j < C; j++) {            // Since values are in decreasing order,            // The area ending with cell (i, j) can            // be obtained by multiplying column number            // with value of hist[i][j]            curr_area = (j + 1) * hist[i][j];            if (curr_area > max_area)                max_area = curr_area;        }    }    return max_area;} // Driver programint main(){    bool mat[R][C] = { { 0, 1, 0, 1, 0 },                       { 0, 1, 0, 1, 1 },                       { 1, 1, 0, 1, 0 } };    cout << "Area of the largest rectangle is " << maxArea(mat);    return 0;}
// Java program to find the largest rectangle of// 1's with swapping of columns allowed.class GFG {     static final int R = 3;    static final int C = 5;     // Returns area of the largest rectangle of 1's    static int maxArea(int mat[][])    {        // An auxiliary array to store count of consecutive 1's        // in every column.        int hist[][] = new int[R + 1][C + 1];         // Step 1: Fill the auxiliary array hist[][]        for (int i = 0; i < C; i++)        {            // First row in hist[][] is copy of first row in mat[][]            hist[0][i] = mat[0][i];             // Fill remaining rows of hist[][]            for (int j = 1; j < R; j++)            {                hist[j][i] = (mat[j][i] == 0) ? 0 : hist[j - 1][i] + 1;            }        }         // Step 2: Sort rows of hist[][] in non-increasing order        for (int i = 0; i < R; i++)        {            int count[] = new int[R + 1];             // counting occurrence            for (int j = 0; j < C; j++)            {                count[hist[i][j]]++;            }             // Traverse the count array from right side            int col_no = 0;            for (int j = R; j >= 0; j--)            {                if (count[j] > 0)                {                    for (int k = 0; k < count[j]; k++)                    {                        hist[i][col_no] = j;                        col_no++;                    }                }            }        }         // Step 3: Traverse the sorted hist[][] to find maximum area        int curr_area, max_area = 0;        for (int i = 0; i < R; i++)        {            for (int j = 0; j < C; j++)            {                // Since values are in decreasing order,                // The area ending with cell (i, j) can                // be obtained by multiplying column number                // with value of hist[i][j]                curr_area = (j + 1) * hist[i][j];                if (curr_area > max_area)                {                    max_area = curr_area;                }            }        }        return max_area;    }     // Driver Code    public static void main(String[] args)    {        int mat[][] = {{0, 1, 0, 1, 0},                       {0, 1, 0, 1, 1},                       {1, 1, 0, 1, 0}};        System.out.println("Area of the largest rectangle is " + maxArea(mat));    }} // This code is contributed by PrinciRaj1992
# Python 3 program to find the largest# rectangle of 1's with swapping# of columns allowed. R = 3C = 5 # Returns area of the largest# rectangle of 1'sdef maxArea(mat):         # An auxiliary array to store count    # of consecutive 1's in every column.    hist = [[0 for i in range(C + 1)]               for i in range(R + 1)]     # Step 1: Fill the auxiliary array hist[][]    for i in range(0, C, 1):                 # First row in hist[][] is copy of        # first row in mat[][]        hist[0][i] = mat[0][i]         # Fill remaining rows of hist[][]        for j in range(1, R, 1):            if ((mat[j][i] == 0)):                hist[j][i] = 0            else:                hist[j][i] = hist[j - 1][i] + 1     # Step 2: Sort rows of hist[][] in    # non-increasing order    for i in range(0, R, 1):        count = [0 for i in range(R + 1)]         # counting occurrence        for j in range(0, C, 1):            count[hist[i][j]] += 1         # Traverse the count array from        # right side        col_no = 0        j = R        while(j >= 0):            if (count[j] > 0):                for k in range(0, count[j], 1):                    hist[i][col_no] = j                    col_no += 1             j -= 1                 # Step 3: Traverse the sorted hist[][]    # to find maximum area    max_area = 0    for i in range(0, R, 1):        for j in range(0, C, 1):                         # Since values are in decreasing order,            # The area ending with cell (i, j) can            # be obtained by multiplying column number            # with value of hist[i][j]            curr_area = (j + 1) * hist[i][j]            if (curr_area > max_area):                max_area = curr_area     return max_area # Driver Codeif __name__ == '__main__':    mat = [[0, 1, 0, 1, 0],           [0, 1, 0, 1, 1],           [1, 1, 0, 1, 0]]    print("Area of the largest rectangle is",                                maxArea(mat))     # This code is contributed by# Shashank_Sharma
// C# program to find the largest rectangle of// 1's with swapping of columns allowed.using System;  class GFG{     static readonly int R = 3;    static readonly int C = 5;     // Returns area of the largest    // rectangle of 1's    static int maxArea(int [,]mat)    {        // An auxiliary array to store count        // of consecutive 1's in every column.        int [,]hist = new int[R + 1, C + 1];         // Step 1: Fill the auxiliary array hist[,]        for (int i = 0; i < C; i++)        {            // First row in hist[,] is copy of            // first row in mat[,]            hist[0, i] = mat[0, i];             // Fill remaining rows of hist[,]            for (int j = 1; j < R; j++)            {                hist[j, i] = (mat[j, i] == 0) ? 0 :                                hist[j - 1, i] + 1;            }        }         // Step 2: Sort rows of hist[,]        // in non-increasing order        for (int i = 0; i < R; i++)        {            int []count = new int[R + 1];             // counting occurrence            for (int j = 0; j < C; j++)            {                count[hist[i, j]]++;            }             // Traverse the count array from right side            int col_no = 0;            for (int j = R; j >= 0; j--)            {                if (count[j] > 0)                {                    for (int k = 0; k < count[j]; k++)                    {                        hist[i, col_no] = j;                        col_no++;                    }                }            }        }         // Step 3: Traverse the sorted hist[,]        // to find maximum area        int curr_area, max_area = 0;        for (int i = 0; i < R; i++)        {            for (int j = 0; j < C; j++)            {                 // Since values are in decreasing order,                // The area ending with cell (i, j) can                // be obtained by multiplying column number                // with value of hist[i,j]                curr_area = (j + 1) * hist[i, j];                if (curr_area > max_area)                {                    max_area = curr_area;                }            }        }        return max_area;    }     // Driver Code    public static void Main()    {        int [,]mat = {{0, 1, 0, 1, 0},                    {0, 1, 0, 1, 1},                    {1, 1, 0, 1, 0}};        Console.WriteLine("Area of the largest rectangle is " +                                                maxArea(mat));    }} //This code is contributed by 29AjayKumar
<script> // JavaScript program to find the largest rectangle of// 1's with swapping of columns allowed.var R = 3;var C = 5;// Returns area of the largest// rectangle of 1'sfunction maxArea(mat){    // An auxiliary array to store count    // of consecutive 1's in every column.    var hist = Array.from(Array(R+1), ()=>Array(C+1));    // Step 1: Fill the auxiliary array hist[,]    for (var i = 0; i < C; i++)    {        // First row in hist[,] is copy of        // first row in mat[,]        hist[0][i] = mat[0][i];        // Fill remaining rows of hist[,]        for (var j = 1; j < R; j++)        {            hist[j][i] = (mat[j][i] == 0) ? 0 :                            hist[j - 1][i] + 1;        }    }    // Step 2: Sort rows of hist[,]    // in non-increasing order    for (var i = 0; i < R; i++)    {        var count = Array(R+1).fill(0);        // counting occurrence        for (var j = 0; j < C; j++)        {            count[hist[i][j]]++;        }        // Traverse the count array from right side        var col_no = 0;        for (var j = R; j >= 0; j--)        {            if (count[j] > 0)            {                for (var k = 0; k < count[j]; k++)                {                    hist[i][col_no] = j;                    col_no++;                }            }        }    }    // Step 3: Traverse the sorted hist[,]    // to find maximum area    var curr_area, max_area = 0;    for (var i = 0; i < R; i++)    {        for (var j = 0; j < C; j++)        {            // Since values are in decreasing order,            // The area ending with cell (i][j) can            // be obtained by multiplying column number            // with value of hist[i,j]            curr_area = (j + 1) * hist[i][j];            if (curr_area > max_area)            {                max_area = curr_area;            }        }    }    return max_area;}// Driver Codevar mat = [[0, 1, 0, 1, 0],            [0, 1, 0, 1, 1],            [1, 1, 0, 1, 0]];document.write("Area of the largest rectangle is " +                                        maxArea(mat));  </script>
Output: 
Area of the largest rectangle is 6
Time complexity of above solution is O(R * (R + C)) where R is number of rows and C is number of columns in input matrix. Extra space: O(R * C)This article is contributed by Shivprasad Choudhary. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
chirag dawra
mjmj
Shashank_Sharma
princiraj1992
29AjayKumar
deesha_chavan
rrrtnx
jayparekh0408
Directi
square-rectangle
Arrays
Matrix
Directi
Arrays
Matrix
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.