Skip to content
Related Articles

Related Articles

Check whether row or column swaps produce maximum size binary sub-matrix with all 1s

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 02 Dec, 2022
Improve Article
Save Article

Given a binary matrix, the task is to find whether row swaps or column swaps give maximum size sub-matrix with all 1’s. In a row swap, we are allowed to swap any two rows. In a column swap, we are allowed to swap any two columns. Output “Row Swap” or “Column Swap” and the maximum size.

Examples: 

Input : 1 1 1
        1 0 1
Output : Column Swap
         4
By swapping column 1 and column 2(0-based indexing), 
index (0, 0) to (1, 1) makes the largest binary 
sub-matrix.

Input : 0 0 0
        1 1 0
        1 1 0
        0 0 0
        1 1 0 
Output : Row Swap
         6

Input : 1 1 0
        0 0 0
        0 0 0
        1 1 0
        1 1 0
        0 0 0
        1 1 0 
Output : Row Swap
         8

The idea is to find both row swap and column swap maximum size binary submatrix and compare.

To find the maximum-sized binary sub-matrix with row swaps allowed, make a 2-D array, say dp[i][j]. Each value of dp[i][j] contains the number of consecutive 1s on right side of (i,j) in i-th row. Now, store each column in the 1-D temporary array one by one, say b[] and sort, and find maximum b[i] * (n – i), since b[i] is indicating the sub-matrix width and (n – i) is sub-matrix height.

Similarly, to find the maximum size binary sub-matrix with column swap allowed, find dp[i][j], where each value contains the number of consecutive 1 below the (i, j) in j-th column. Similarly, store each row in the 1-D temporary array one by one, say b[] and sort. Find maximum b[i] * (m – i), since b[i] is indicating the submatrix height and (n – i) is submatrix width.

Below is the implementation of this approach: 

C++




// C++ program to find maximum binary sub-matrix
// with row swaps and column swaps.
#include <bits/stdc++.h>
#define R 5
#define C 3
using namespace std;
 
// Precompute the number of consecutive 1 below the
// (i, j) in j-th column and the number of consecutive 1s
// on right side of (i, j) in i-th row.
void precompute(int mat[R][C], int ryt[][C + 2],
                               int dwn[R + 2][C + 2])
{
    // Traversing the 2d matrix from top-right.
    for (int j=C-1; j>=0; j--)
    {
        for (int i=0; i<R; ++i)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                ryt[i][j] = 0;
 
            // Counting consecutive 1 on right side
            else
                ryt[i][j] = ryt[i][j + 1] + 1;
        }
    }
 
 
    // Traversing the 2d matrix from bottom-left.
    for (int i = R - 1; i >= 0; i--)
    {
        for (int j = 0; j < C; ++j)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                dwn[i][j] = 0;
 
            // Counting consecutive 1 down to (i,j).
            else
                dwn[i][j] = dwn[i + 1][j] + 1;
        }
    }
}
 
// Return maximum size submatrix with row swap allowed.
int solveRowSwap(int ryt[R + 2][C + 2])
{
    int b[R] = { 0 }, ans = 0;
 
    for (int j=0; j<C; j++)
    {
        // Copying the column
        for (int i=0; i<R; i++)
            b[i] = ryt[i][j];
 
        // Sort the copied array
        sort(b, b + R);
 
        // Find maximum submatrix size.
        for (int i = 0; i < R; ++i)
            ans = max(ans, b[i] * (R - i));
    }
 
    return ans;
}
 
// Return maximum size submatrix with column
// swap allowed.
int solveColumnSwap(int dwn[R + 2][C + 2])
{
    int b[C] = { 0 }, ans = 0;
 
    for (int i = 0; i < R; ++i)
    {
        // Copying the row.
        for (int j = 0; j < C; ++j)
            b[j] = dwn[i][j];
 
        // Sort the copied array
        sort(b, b + C);
 
        // Find maximum submatrix size.
        for (int i = 0; i < C; ++i)
            ans = max(ans, b[i] * (C - i));
    }
 
    return ans;
}
 
void findMax1s(int mat[R][C])
{
    int ryt[R + 2][C + 2], dwn[R + 2][C + 2];
    memset(ryt, 0, sizeof ryt);
    memset(dwn, 0, sizeof dwn);
 
    precompute(mat, ryt, dwn);
 
    // Solving for row swap and column swap
    int rswap = solveRowSwap(ryt);
    int cswap = solveColumnSwap(dwn);
 
    // Comparing both.
    (rswap > cswap)? (cout << "Row Swap\n" << rswap << endl):
                     (cout << "Column Swap\n" << cswap << endl);
}
 
// Driven Program
int main()
{
    int mat[R][C] = {{ 0, 0, 0 },
                     { 1, 1, 0 },
                     { 1, 1, 0 },
                     { 0, 0, 0 },
                     { 1, 1, 0 }};
 
    findMax1s(mat);
    return 0;
}

Java




import java.util.Arrays;
 
// Java program to find maximum binary sub-matrix
// with row swaps and column swaps.
class GFG {
 
    static int R = 5;
    static int C = 3;
 
// Precompute the number of consecutive 1 below the
// (i, j) in j-th column and the number of consecutive 1s
// on right side of (i, j) in i-th row.
    static void precompute(int mat[][], int ryt[][],
            int dwn[][]) {
        // Traversing the 2d matrix from top-right.
        for (int j = C - 1; j >= 0; j--) {
            for (int i = 0; i < R; ++i) {
                // If (i,j) contain 0, do nothing
                if (mat[i][j] == 0) {
                    ryt[i][j] = 0;
                } // Counting consecutive 1 on right side
                else {
                    ryt[i][j] = ryt[i][j + 1] + 1;
                }
            }
        }
 
        // Traversing the 2d matrix from bottom-left.
        for (int i = R - 1; i >= 0; i--) {
            for (int j = 0; j < C; ++j) {
                // If (i,j) contain 0, do nothing
                if (mat[i][j] == 0) {
                    dwn[i][j] = 0;
                } // Counting consecutive 1 down to (i,j).
                else {
                    dwn[i][j] = dwn[i + 1][j] + 1;
                }
            }
        }
    }
 
// Return maximum size submatrix with row swap allowed.
    static int solveRowSwap(int ryt[][]) {
        int b[] = new int[R], ans = 0;
 
        for (int j = 0; j < C; j++) {
            // Copying the column
            for (int i = 0; i < R; i++) {
                b[i] = ryt[i][j];
            }
 
            // Sort the copied array
            Arrays.sort(b);
 
            // Find maximum submatrix size.
            for (int i = 0; i < R; ++i) {
                ans = Math.max(ans, b[i] * (R - i));
            }
        }
 
        return ans;
    }
 
// Return maximum size submatrix with column
// swap allowed.
    static int solveColumnSwap(int dwn[][]) {
        int b[] = new int[C], ans = 0;
 
        for (int i = 0; i < R; ++i) {
            // Copying the row.
            for (int j = 0; j < C; ++j) {
                b[j] = dwn[i][j];
            }
 
            // Sort the copied array
            Arrays.sort(b);
 
            // Find maximum submatrix size.
            for (int k = 0; k < C; ++k) {
                ans = Math.max(ans, b[k] * (C - k));
            }
        }
 
        return ans;
    }
 
    static void findMax1s(int mat[][]) {
        int ryt[][] = new int[R + 2][C + 2], dwn[][] = new int[R + 2][C + 2];
 
        precompute(mat, ryt, dwn);
 
        // Solving for row swap and column swap
        int rswap = solveRowSwap(ryt);
        int cswap = solveColumnSwap(dwn);
 
        // Comparing both.
        if (rswap > cswap) {
            System.out.println("Row Swap\n" + rswap);
        } else {
            System.out.println("Column Swap\n" + cswap);
        }
    }
 
// Driven Program
    public static void main(String[] args) {
        int mat[][] = {{0, 0, 0},
        {1, 1, 0},
        {1, 1, 0},
        {0, 0, 0},
        {1, 1, 0}};
 
        findMax1s(mat);
    }
}
 
/* This Java code is contributed by PrinciRaj1992*/

Python3




# Python3 program to find maximum binary
# sub-matrix with row swaps and column swaps.
R, C = 5, 3
 
# Precompute the number of consecutive 1
# below the (i, j) in j-th column and the
# number of consecutive 1s on right side
# of (i, j) in i-th row.
def precompute(mat, ryt, dwn):
 
    # Traversing the 2d matrix from top-right.
    for j in range(C - 1, -1, -1):
     
        for i in range(0, R):
         
            # If (i,j) contain 0, do nothing
            if mat[i][j] == 0:
                ryt[i][j] = 0
 
            # Counting consecutive 1 on right side
            else:
                ryt[i][j] = ryt[i][j + 1] + 1
         
    # Traversing the 2d matrix from bottom-left.
    for i in range(R - 1, -1, -1):
     
        for j in range(0, C):
         
            # If (i,j) contain 0, do nothing
            if mat[i][j] == 0:
                dwn[i][j] = 0
 
            # Counting consecutive 1 down to (i,j).
            else:
                dwn[i][j] = dwn[i + 1][j] + 1
 
# Return maximum size submatrix
# with row swap allowed.
def solveRowSwap(ryt):
 
    b = [0] * R
    ans = 0
 
    for j in range(0, C):
     
        # Copying the column
        for i in range(0, R):
            b[i] = ryt[i][j]
 
        # Sort the copied array
        b.sort()
 
        # Find maximum submatrix size.
        for i in range(0, R):
            ans = max(ans, b[i] * (R - i))
     
    return ans
 
# Return maximum size submatrix
# with column swap allowed.
def solveColumnSwap(dwn):
 
    b = [0] * C
    ans = 0
 
    for i in range(0, R):
     
        # Copying the row.
        for j in range(0, C):
            b[j] = dwn[i][j]
 
        # Sort the copied array
        b.sort()
 
        # Find maximum submatrix size.
        for i in range(0, C):
            ans = max(ans, b[i] * (C - i))
     
    return ans
 
def findMax1s(mat):
 
    ryt = [[0 for i in range(C + 2)]
              for j in range(R + 2)]
    dwn = [[0 for i in range(C + 2)]
              for j in range(R + 2)]
     
    precompute(mat, ryt, dwn)
 
    # Solving for row swap and column swap
    rswap = solveRowSwap(ryt)
    cswap = solveColumnSwap(dwn)
 
    # Comparing both.
    if rswap > cswap: print("Row Swap\n", rswap)
    else: print("Column Swap\n", cswap)
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[0, 0, 0],
           [1, 1, 0],
           [1, 1, 0],
           [0, 0, 0],
           [1, 1, 0]]
 
    findMax1s(mat)
     
# This code is contributed by Rituraj Jain

C#




// C# program to find maximum binary sub-matrix
// with row swaps and column swaps.
using System;
public class GFG {
  
    static int R = 5;
    static int C = 3;
  
// Precompute the number of consecutive 1 below the
// (i, j) in j-th column and the number of consecutive 1s
// on right side of (i, j) in i-th row.
    static void precompute(int [,]mat, int [,]ryt,
            int [,]dwn) {
        // Traversing the 2d matrix from top-right.
        for (int j = C - 1; j >= 0; j--) {
            for (int i = 0; i < R; ++i) {
                // If (i,j) contain 0, do nothing
                if (mat[i,j] == 0) {
                    ryt[i,j] = 0;
                } // Counting consecutive 1 on right side
                else {
                    ryt[i,j] = ryt[i,j + 1] + 1;
                }
            }
        }
  
        // Traversing the 2d matrix from bottom-left.
        for (int i = R - 1; i >= 0; i--) {
            for (int j = 0; j < C; ++j) {
                // If (i,j) contain 0, do nothing
                if (mat[i,j] == 0) {
                    dwn[i,j] = 0;
                } // Counting consecutive 1 down to (i,j).
                else {
                    dwn[i,j] = dwn[i + 1,j] + 1;
                }
            }
        }
    }
  
// Return maximum size submatrix with row swap allowed.
    static int solveRowSwap(int [,]ryt) {
        int []b = new int[R]; int ans = 0;
  
        for (int j = 0; j < C; j++) {
            // Copying the column
            for (int i = 0; i < R; i++) {
                b[i] = ryt[i,j];
            }
  
            // Sort the copied array
            Array.Sort(b);
  
            // Find maximum submatrix size.
            for (int i = 0; i < R; ++i) {
                ans = Math.Max(ans, b[i] * (R - i));
            }
        }
  
        return ans;
    }
  
// Return maximum size submatrix with column
// swap allowed.
    static int solveColumnSwap(int [,]dwn) {
        int []b = new int[C];int ans = 0;
  
        for (int i = 0; i < R; ++i) {
            // Copying the row.
            for (int j = 0; j < C; ++j) {
                b[j] = dwn[i,j];
            }
  
            // Sort the copied array
            Array.Sort(b);
  
            // Find maximum submatrix size.
            for (int k = 0; k < C; ++k) {
                ans = Math.Max(ans, b[k] * (C - k));
            }
        }
  
        return ans;
    }
  
    static void findMax1s(int [,]mat) {
        int [,]ryt = new int[R + 2,C + 2];
        int [,]dwn = new int[R + 2,C + 2];
  
        precompute(mat, ryt, dwn);
  
        // Solving for row swap and column swap
        int rswap = solveRowSwap(ryt);
        int cswap = solveColumnSwap(dwn);
  
        // Comparing both.
        if (rswap > cswap) {
            Console.WriteLine("Row Swap\n" + rswap);
        } else {
            Console.WriteLine("Column Swap\n" + cswap);
        }
    }
  
// Driven Program
    public static void Main() {
        int [,]mat = {{0, 0, 0},
        {1, 1, 0},
        {1, 1, 0},
        {0, 0, 0},
        {1, 1, 0}};
  
        findMax1s(mat);
    }
}
  
/* This C# code is contributed by PrinciRaj1992*/

Javascript




// JS program to find maximum binary sub-matrix
// with row swaps and column swaps.
 
let R = 5
let C = 3
 
// Precompute the number of consecutive 1 below the
// (i, j) in j-th column and the number of consecutive 1s
// on right side of (i, j) in i-th row.
function precompute( mat,  ryt, dwn)
{
    // Traversing the 2d matrix from top-right.
    for (var j=C-1; j>=0; j--)
    {
        for (var i=0; i<R; ++i)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                ryt[i][j] = 0;
 
            // Counting consecutive 1 on right side
            else
                ryt[i][j] = ryt[i][j + 1] + 1;
        }
    }
 
 
    // Traversing the 2d matrix from bottom-left.
    for (var i = R - 1; i >= 0; i--)
    {
        for (var  j = 0; j < C; ++j)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                dwn[i][j] = 0;
 
            // Counting consecutive 1 down to (i,j).
            else
                dwn[i][j] = dwn[i + 1][j] + 1;
        }
    }
}
 
// Return maximum size submatrix with row swap allowed.
function solveRowSwap( ryt)
{
    let b = new Array(R).fill(0)
    let ans = 0;
 
    for (var j=0; j<C; j++)
    {
        // Copying the column
        for (var i=0; i<R; i++)
            b[i] = ryt[i][j];
 
        // Sort the copied array
        b.sort(function(x, y) { return x - y})
 
        // Find maximum submatrix size.
        for (var i = 0; i < R; ++i)
            ans = Math.max(ans, b[i] * (R - i));
    }
 
    return ans;
}
 
// Return maximum size submatrix with column
// swap allowed.
function solveColumnSwap( dwn)
{
    let b = new Array(C).fill(0)
    let ans = 0;
 
    for (var i = 0; i < R; ++i)
    {
        // Copying the row.
        for (var j = 0; j < C; ++j)
            b[j] = dwn[i][j];
 
        // Sort the copied array
        b.sort(function(x, y) { return x - y})
 
        // Find maximum submatrix size.
        for (var i = 0; i < C; ++i)
            ans = Math.max(ans, b[i] * (C - i));
    }
 
    return ans;
}
 
function findMax1s( mat)
{
    let ryt = new Array(R + 2)
    let dwn = new Array(R + 2)
    for (var i = 0; i < R + 2; i++)
    {
        ryt[i] = new Array(C + 2).fill(0)
        dwn[i] = new Array(C + 2).fill(0)
    }
 
    precompute(mat, ryt, dwn);
 
    // Solving for row swap and column swap
    rswap = solveRowSwap(ryt);
    cswap = solveColumnSwap(dwn);
 
    // Comparing both.
    if (rswap > cswap)
        console.log("Row Swap\n" + rswap)
    else
        console.log("Column Swap\n" + cswap);
}
 
// Driven Program
let  mat= [[ 0, 0, 0 ],
                     [ 1, 1, 0 ],
                     [ 1, 1, 0 ],
                     [ 0, 0, 0 ],
                     [ 1, 1, 0 ]];
 
findMax1s(mat);
 
// This code is contributed by phasing17.

Output

Row Swap
6

Time Complexity: O(R*C* log(C))
Auxiliary Space: O(R*C)

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!