Open In App

Maximize 1s after Flipping exactly one row and one column in given Binary Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary matrix mat[][]. The task is to find the maximum 1’s that can be obtained after flipping all the elements of exactly one row followed by flipping all elements of exactly one column.

Example:

Input: mat[][]  = {{1, 0, 1}, {0, 1, 0}, {1, 0, 0}}
Output: 8
Explanation: Flip row 1 to get: 
{{1, 0, 1},  
 {1, 0, 1},  
 {1, 0, 0}}
And then flip column 1 to get: 
{{1, 1, 1},  
 {1, 1, 1},  
 {1, 1, 0}}

Input: mat[][] = { { 1, 1, 1 }, { 0, 1, 1 }, { 0, 0, 1 } }
Output: 6
Explanation: Flip row 1 to get: 
{{1, 1, 1},  
 {1, 0, 0},  
 {0, 0, 1}}
And then flip column 1 to get: 
{{1, 0, 1},  
 {1, 1, 0},  
 {0, 1, 1}}

 

Approach: The approach is based on the precomputation technique and traversal of the array. Follow the steps to solve the problem.

  • Maintain a rows[] array which stores the amount of 1s obtained after flipping a respective row.
  • Also, maintain a cols[] array which stores the amount of 1s obtained after flipping a respective column.
  • Then count the total number of 1s in the entire matrix.
  • Simply traverse on each row and column pair and maintain a maxi variable which is the global max amount of 1s obtained after flipping both row and column.
  • Keep a note that if a column and row are both flipped, the square in which they overlap will still remain the same.
  • To account for this, after calculation of the flips for row r and column c, if
    • the value at mat[r] is 0, subtract two because then, there would be over-counting.
    • but if the value at mat[r] is 1, simply add two because then, there would be under-counting.

Below is the implementation of the above approach :

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum 1s
int maximizeOnes(vector<vector<int> >& mat,
                 int n, int m)
{
    // int n = arr.size();
    // int m = arr[0].size();
    vector<int> rows(n);
    vector<int> cols(m);
    int total = 0, maxi = INT_MIN, sum = 0;
    for (int i = 0; i < m; i++) {
 
        // Sum is a temporary tracker
        // For each row and column
        sum = 0;
        for (int j = 0; j < n; j++) {
            sum += mat[j][i] == 0 ? 1 : -1;
        }
 
        // Count of 1's after flip
        // In each column
        cols[i] = sum;
    }
    for (int i = 0; i < n; i++) {
        sum = 0;
        for (int j = 0; j < m; j++) {
            sum += mat[i][j] == 0 ? 1 : -1;
 
            // Total number of 1s in matrix
            total += mat[i][j];
        }
 
        // Count of 1's after flip
        // In each row
        rows[i] = sum;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // No. of 1's after
            // Flipping row and column
            int temp = cols[j] + rows[i];
 
            // Overlapping condition
            // As mentioned above
            temp
                += mat[i][j] == 1 ? 2 : -2;
 
            // Updating the global maxi value
            maxi = max(maxi, temp);
        }
    }
    return total + maxi;
}
 
// Driver code
int main()
{
    int N = 3;
    int M = 3;
    vector<vector<int> > mat
        = { { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } };
    cout << maximizeOnes(mat, N, M) << "\n";
    return 0;
}


Java




// JAVA code for the above approach:
import java.util.*;
class GFG
{
 
  // Function to find the maximum 1s
  public static int
    maximizeOnes(ArrayList<ArrayList<Integer> > mat, int n,
                 int m)
  {
     
    // int n = arr.size();
    // int m = arr[0].size();
    int rows[] = new int[n];
    int cols[] = new int[m];
    int total = 0, maxi = Integer.MIN_VALUE, sum = 0;
    for (int i = 0; i < m; i++) {
 
      // Sum is a temporary tracker
      // For each row and column
      sum = 0;
      for (int j = 0; j < n; j++) {
        sum += mat.get(j).get(i) == 0 ? 1 : -1;
      }
 
      // Count of 1's after flip
      // In each column
      cols[i] = sum;
    }
    for (int i = 0; i < n; i++) {
      sum = 0;
      for (int j = 0; j < m; j++) {
        sum += mat.get(i).get(j) == 0 ? 1 : -1;
 
        // Total number of 1s in matrix
        total += mat.get(i).get(j);
      }
 
      // Count of 1's after flip
      // In each row
      rows[i] = sum;
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // No. of 1's after
        // Flipping row and column
        int temp = cols[j] + rows[i];
 
        // Overlapping condition
        // As mentioned above
        temp += mat.get(i).get(j) == 1 ? 2 : -2;
 
        // Updating the global maxi value
        maxi = Math.max(maxi, temp);
      }
    }
    return total + maxi;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int N = 3;
    int M = 3;
    ArrayList<ArrayList<Integer> > mat
      = new ArrayList<ArrayList<Integer> >();
    ArrayList<Integer> temp1 = new ArrayList<Integer>(
      Arrays.asList(1, 0, 1));
    ArrayList<Integer> temp2 = new ArrayList<Integer>(
      Arrays.asList(0, 1, 0));
    ArrayList<Integer> temp3 = new ArrayList<Integer>(
      Arrays.asList(1, 0, 0));
    mat.add(temp1);
    mat.add(temp2);
    mat.add(temp3);
    System.out.println(maximizeOnes(mat, N, M));
  }
}
 
// This code is contributed by Taranpreet


Python3




# Python code for the above approach
 
# Function to find the maximum 1s
import sys
def maximizeOnes(mat,n, m):
         
    # int n = arr.size();
    # int m = arr[0].size();
    rows = [0]*n
    cols = [0]*m
    total,maxi,sum = 0,-sys.maxsize-1,0
    for i in range(m):
 
        # Sum is a temporary tracker
        # For each row and column
        sum = 0
        for j in range(n):
            sum += 1 if mat[j][i] == 0 else -1
 
        # Count of 1's after flip
        # In each column
        cols[i] = sum
 
    for i in range(n):
        sum = 0
        for j in range(m):
 
            sum += 1 if mat[i][j] == 0 else -1
 
            # Total number of 1s in matrix
            total += mat[i][j]
 
        # Count of 1's after flip
        # In each row
        rows[i] = sum
 
    for i in range(n):
        for j in range(m):
 
            # No. of 1's after
            # Flipping row and column
            temp = cols[j] + rows[i]
 
            # Overlapping condition
            # As mentioned above
            temp += 2 if mat[i][j] == 1 else -2
 
            # Updating the global maxi value
            maxi = max(maxi, temp)
 
    return total + maxi
 
# Driver code
N = 3
M = 3
mat = [[1, 0, 1], [0, 1, 0], [1, 0, 0]]
print(maximizeOnes(mat, N, M))
 
# This code is contributed by shinjanpatra


C#




// C# code for the above approach:
using System;
class GFG {
 
  // Function to find the maximum 1s
  static int maximizeOnes(int[, ] mat, int n, int m)
  {
 
    // int n = arr.size();
    // int m = arr[0].size();
    int[] rows = new int[n];
    int[] cols = new int[m];
    int total = 0, maxi = Int32.MinValue, sum = 0;
    for (int i = 0; i < m; i++) {
 
      // Sum is a temporary tracker
      // For each row and column
      sum = 0;
      for (int j = 0; j < n; j++) {
        sum += mat[j, i] == 0 ? 1 : -1;
      }
 
      // Count of 1's after flip
      // In each column
      cols[i] = sum;
    }
    for (int i = 0; i < n; i++) {
      sum = 0;
      for (int j = 0; j < m; j++) {
        sum += mat[i, j] == 0 ? 1 : -1;
 
        // Total number of 1s in matrix
        total += mat[i, j];
      }
 
      // Count of 1's after flip
      // In each row
      rows[i] = sum;
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // No. of 1's after
        // Flipping row and column
        int temp = cols[j] + rows[i];
 
        // Overlapping condition
        // As mentioned above
        temp += mat[i, j] == 1 ? 2 : -2;
 
        // Updating the global maxi value
        maxi = Math.Max(maxi, temp);
      }
    }
    return total + maxi;
  }
 
  // Driver code
  public static void Main()
  {
    int N = 3;
    int M = 3;
    int[, ] mat
      = { { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } };
    Console.WriteLine(maximizeOnes(mat, N, M));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
       // JavaScript code for the above approach
 
       // Function to find the maximum 1s
       function maximizeOnes(mat,
           n, m)
       {
        
           // int n = arr.size();
           // int m = arr[0].size();
           let rows = new Array(n);
           let cols = new Array(m);
           let total = 0, maxi = Number.MIN_VALUE, sum = 0;
           for (let i = 0; i < m; i++) {
 
               // Sum is a temporary tracker
               // For each row and column
               sum = 0;
               for (let j = 0; j < n; j++) {
                   sum += mat[j][i] == 0 ? 1 : -1;
               }
 
               // Count of 1's after flip
               // In each column
               cols[i] = sum;
           }
           for (let i = 0; i < n; i++) {
               sum = 0;
               for (let j = 0; j < m; j++) {
                   sum += mat[i][j] == 0 ? 1 : -1;
 
                   // Total number of 1s in matrix
                   total += mat[i][j];
               }
 
               // Count of 1's after flip
               // In each row
               rows[i] = sum;
           }
           for (let i = 0; i < n; i++) {
               for (let j = 0; j < m; j++) {
 
                   // No. of 1's after
                   // Flipping row and column
                   let temp = cols[j] + rows[i];
 
                   // Overlapping condition
                   // As mentioned above
                   temp
                       += mat[i][j] == 1 ? 2 : -2;
 
                   // Updating the global maxi value
                   maxi = Math.max(maxi, temp);
               }
           }
           return total + maxi;
       }
 
       // Driver code
       let N = 3;
       let M = 3;
       let mat
           = [[1, 0, 1], [0, 1, 0], [1, 0, 0]];
       document.write(maximizeOnes(mat, N, M) + '<br>');
 
    // This code is contributed by Potta Lokesh
   </script>


 
 

Output

8

 

Time Complexity: O(N * M), The algorithm involves iterating through the matrix thrice, once to calculate the sum of each row, once to calculate the sum of each column, and once to iterate over each cell and compute the maximum number of 1s that can be obtained by flipping the corresponding row and column. Therefore, the time complexity of the algorithm is O(N * M), where n and m are the number of rows and columns in the matrix, respectively.
Auxiliary Space: O(N + M), The algorithm uses three additional vectors of size n and m to store the sums of each row and column, and a few constant variables. Therefore, the space complexity of the algorithm is O(N + M).

 



Last Updated : 08 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads