Open In App

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

Last Updated : 12 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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's
int 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 program
int 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




// Java program to find the largest rectangle of
// 1's with swapping of columns allowed.
import java.util.*;
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


Python3




# Python 3 program to find the largest
# rectangle of 1's with swapping
# of columns allowed.
 
R = 3
C = 5
 
# Returns area of the largest
# rectangle of 1's
def 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 Code
if __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#




// 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


Javascript




<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's
function 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 Code
var 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)

 



Similar Reads

Largest subset of rectangles such that no rectangle fit in any other rectangle
Given height and width of N rectangles. The task is to find the size of the largest subset such that no pair of rectangles fit within each other. Note that if H1 ? H2 and W1 ? W2 then rectangle 1 fits inside rectangle 2. Examples: Input: arr[] = {{1, 3}, {2, 2}, {1, 3}} Output: 2 The required sub-set is {{1, 3}, {2, 2}} {1, 3} is included only once
15 min read
Sort an array with swapping only with a special element is allowed
Given an array of length n + 1, containing elements 1 through n and a space, Requires the use of a given swap (index i, index j) function to sort the array, You can only swap the gap and a number, in the end, put the gap at the end. There will be a number 999 in the array as a gap or space. Examples: Input : arr = {1, 5, 4, 999, 3, 2} Output : arr
10 min read
Number of swaps to sort when only adjacent swapping allowed
Given an array arr[] of non negative integers. We can perform a swap operation on any two adjacent elements in the array. Find the minimum number of swaps needed to sort the array in ascending order. Examples : Input : arr[] = {3, 2, 1}Output : 3We need to do following swaps (3, 2), (3, 1) and (1, 2) Input : arr[] = {1, 20, 6, 4, 5}Output : 5 Recom
13 min read
Check if it is possible to sort an array with conditional swapping of adjacent allowed
We are given an unsorted array of integers in the range from 0 to n-1. We are allowed to swap adjacent elements in array many number of times but only if the absolute difference between these element is 1. Check if it is possible to sort the array.If yes then print "yes" else "no". Examples: Input : arr[] = {1, 0, 3, 2} Output : yes Explanation:- W
5 min read
Ratio of area of a rectangle with the rectangle inscribed in it
Given two rectangles, X with a ratio of length to width a:b and Y with a ratio of length to width c:d respectively. Both the rectangles can be resized as long as the ratio of sides remains the same. The task is to place the second rectangle inside the first rectangle such that at least 1 side is equal and that side overlaps of both the rectangles a
7 min read
Maximum area of a Rectangle that can be circumscribed about a given Rectangle of size LxW
Given a rectangle of dimensions L and W. The task is to find the maximum area of a rectangle that can be circumscribed about a given rectangle with dimensions L and W. Examples: Input: L = 10, W = 10Output: 200 Input: L = 18, W = 12Output: 450 Approach: Let below is the given rectangle EFGH of dimensions L and W. We have to find the area of rectang
4 min read
Count ways to reach target cell in a rectangle with restricted sub-rectangle
Given a grid of size M x N and two integers X and Y. A restricted area is defined as the lower left sub-rectangle consisting of X x Y blocks. Starting from the upper left cell find the number of ways to reach the bottom right cell where a legal move is defined to move right or down but never into the restricted area or outside the given grid.  Note
13 min read
C++ Program For Swapping Nodes In A Linked List Without Swapping Data
Given a linked list and two keys in it, swap nodes for two given keys. Nodes should be swapped by changing links. Swapping data of nodes may be expensive in many situations when data contains many fields. It may be assumed that all keys in the linked list are distinct. Examples: Input : 10-&gt;15-&gt;12-&gt;13-&gt;20-&gt;14, x = 12, y = 20 Output:
5 min read
C Program For Swapping Nodes In A Linked List Without Swapping Data
Given a linked list and two keys in it, swap nodes for two given keys. Nodes should be swapped by changing links. Swapping data of nodes may be expensive in many situations when data contains many fields. It may be assumed that all keys in the linked list are distinct. Examples: Input : 10-&gt;15-&gt;12-&gt;13-&gt;20-&gt;14, x = 12, y = 20 Output:
4 min read
Java Program For Swapping Nodes In A Linked List Without Swapping Data
Given a linked list and two keys in it, swap nodes for two given keys. Nodes should be swapped by changing links. Swapping data of nodes may be expensive in many situations when data contains many fields. It may be assumed that all keys in the linked list are distinct. Examples: Input : 10-&gt;15-&gt;12-&gt;13-&gt;20-&gt;14, x = 12, y = 20 Output:
6 min read
Article Tags :
Practice Tags :