Maximize the binary matrix by flipping submatrix once
Given a binary matrix of R rows and C columns. We are allowed to flip to any size of sub matrix. Flipping means changing 1 to 0 and 0 to 1. The task is to maximize the number of 1s in the matrix. Output the maximum number of 1s.
Examples:
Input : R = 3, C =3 mat[][] = { 0, 0, 1, 0, 0, 1, 1, 0, 1 } Output : 8 Flip 0 0 1 0 0 1 1 0 1 to get 1 1 1 1 1 1 0 1 1 Input : R = 2, C = 3 mat[][] = { 0, 0, 0, 0, 0, 0 } Output : 6
Create a matrix ones[][] of R rows and C columns, which precomputes the number of ones in the submatrix from (0, 0) to (i, j) by
// Common elements in ones[i-1][j] and // ones[i][j-1] are ones[i-1][j-1] ones[i][j] = ones[i-1][j] + ones[i][j-1] - ones[i-1][j-1] + (mat[i][j] == 1)
Since, we are allowed to flip sub matrix only once. We iterate over all possible submatrix of all possible sizes for each cell (i, j) to (i + k – 1, i + k – 1). We calculate the total number of ones after the digits are filliped in the chosen submatrix.
Total number of ones in the final matrix after flipping submatrix (i, j) to (i + k – 1) will be Ones in the whole matrix – Ones in the chosen submatrix + Zeroes in the chosen sub matrix. That comes out to be :-
ones[R][C] - cal(i, j, i + k-1, j + k - 1) + k*k - cal(i, j, i + k - 1, j + k - 1) where cal(a, b, c, d) denotes the number of ones in square submatrix of length c - a. Now cal(x1, y1, x2, y2) can be define by: ones[x2][y2] - ones[x2][y1 - 1] - ones[x1 - 1][y2] + ones[x1 - 1][y1 - 1].
Below is the implementation of this approach:
C++
// C++ program to find maximum number of ones after // one flipping in Binary Matrix #include <bits/stdc++.h> #define R 3 #define C 3 using namespace std; // Return number of ones in square submatrix of size // k x k starting from (x, y) int cal( int ones[R + 1][C + 1], int x, int y, int k) { return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1] - ones[x + k - 1][y - 1] + ones[x - 1][y - 1]; } // Return maximum number of 1s after flipping a submatrix int sol( int mat[R][C]) { int ans = 0; // Precomputing the number of 1s int ones[R + 1][C + 1] = {0}; for ( int i = 1; i <= R; i++) for ( int j = 1; j <= C; j++) ones[i][j] = ones[i - 1][j] + ones[i][j - 1] - ones[i - 1][j - 1] + (mat[i - 1][j - 1] == 1); // Finding the maximum number of 1s after flipping for ( int k = 1; k <= min(R, C); k++) for ( int i = 1; i + k - 1 <= R; i++) for ( int j = 1; j + k - 1 <= C; j++) ans = max(ans, (ones[R][C] + k * k - 2 * cal(ones, i, j, k))); return ans; } // Driver code int main() { int mat[R][C] = {{0, 0, 1}, { 0, 0, 1}, { 1, 0, 1 } }; cout << sol(mat) << endl; return 0; } |
Java
// Java program to find maximum number of ones after // one flipping in Binary Matrix class GFG { static final int R = 3 ; static final int C = 3 ; // Return number of ones in square submatrix of size // k x k starting from (x, y) static int cal( int ones[][], int x, int y, int k) { return ones[x + k - 1 ][y + k - 1 ] - ones[x - 1 ][y + k - 1 ] - ones[x + k - 1 ][y - 1 ] + ones[x - 1 ][y - 1 ]; } // Return maximum number of 1s after flipping a submatrix static int sol( int mat[][]) { int ans = 0 ; int val = 0 ; // Precomputing the number of 1s int ones[][] = new int [R + 1 ][C + 1 ]; for ( int i = 1 ; i <= R; i++) for ( int j = 1 ; j <= C; j++) { if (mat[i - 1 ][j - 1 ] == 1 ) val= 1 ; ones[i][j] = ones[i - 1 ][j] + ones[i][j - 1 ] - ones[i - 1 ][j - 1 ] + (val); } // Finding the maximum number of 1s after flipping for ( int k = 1 ; k <= Math.min(R, C); k++) for ( int i = 1 ; i + k - 1 <= R; i++) for ( int j = 1 ; j + k - 1 <= C; j++) ans = Math.max(ans, (ones[R][C] + k * k - 2 * cal(ones, i, j, k))); return ans; } // Driver code static public void main(String[] args) { int mat[][] = {{ 0 , 0 , 1 }, { 0 , 0 , 1 }, { 1 , 0 , 1 } }; System.out.println(sol(mat)); } } // This code is contributed by Rajput-Ji |
Python3
# Python 3 program to find maximum number of # ones after one flipping in Binary Matrix R = 3 C = 3 # Return number of ones in square submatrix # of size k x k starting from (x, y) def cal(ones, x, y, k): return (ones[x + k - 1 ][y + k - 1 ] - ones[x - 1 ][y + k - 1 ] - ones[x + k - 1 ][y - 1 ] + ones[x - 1 ][y - 1 ]) # Return maximum number of 1s after # flipping a submatrix def sol(mat): ans = 0 # Precomputing the number of 1s ones = [[ 0 for i in range (C + 1 )] for i in range (R + 1 )] for i in range ( 1 , R + 1 , 1 ): for j in range ( 1 , C + 1 , 1 ): ones[i][j] = (ones[i - 1 ][j] + ones[i][j - 1 ] - ones[i - 1 ][j - 1 ] + (mat[i - 1 ][j - 1 ] = = 1 )) # Finding the maximum number of 1s # after flipping for k in range ( 1 , min (R, C) + 1 , 1 ): for i in range ( 1 , R - k + 2 , 1 ): for j in range ( 1 , C - k + 2 , 1 ): ans = max (ans, (ones[R][C] + k * k - 2 * cal(ones, i, j, k))) return ans # Driver code if __name__ = = '__main__' : mat = [[ 0 , 0 , 1 ], [ 0 , 0 , 1 ], [ 1 , 0 , 1 ]] print (sol(mat)) # This code is contributed by # Sahil_Shelangia |
C#
// C# program to find maximum number of ones after // one flipping in Binary Matrix using System; public class GFG { static readonly int R = 3; static readonly int C = 3 ; // Return number of ones in square submatrix of size // k x k starting from (x, y) static int cal( int [,]ones, int x, int y, int k) { return ones[x + k - 1,y + k - 1] - ones[x - 1,y + k - 1] - ones[x + k - 1,y - 1] + ones[x - 1,y - 1]; } // Return maximum number of 1s after flipping a submatrix static int sol( int [,]mat) { int ans = 0; int val =0; // Precomputing the number of 1s int [,]ones = new int [R + 1,C + 1]; for ( int i = 1; i <= R; i++) for ( int j = 1; j <= C; j++) { if (mat[i - 1,j - 1] == 1) val=1; ones[i,j] = ones[i - 1,j] + ones[i,j - 1] - ones[i - 1,j - 1] + (val); } // Finding the maximum number of 1s after flipping for ( int k = 1; k <= Math.Min(R, C); k++) for ( int i = 1; i + k - 1 <= R; i++) for ( int j = 1; j + k - 1 <= C; j++) ans = Math.Max(ans, (ones[R,C] + k * k - 2 * cal(ones, i, j, k))); return ans; } // Driver code static public void Main() { int [,]mat = {{0, 0, 1}, { 0, 0, 1}, { 1, 0, 1 } }; Console.WriteLine(sol(mat)); } } // This code is contributed by 29AjayKumar |
PHP
<?php // PHP program to find maximum number of ones after // one flipping in Binary Matrix $R = 3; $C = 3; // Return number of ones in square submatrix of size // k x k starting from (x, y) function cal( $ones , $x , $y , $k ) { return $ones [ $x + $k - 1][ $y + $k - 1] - $ones [ $x - 1][ $y + $k - 1] - $ones [ $x + $k - 1][ $y - 1] + $ones [ $x - 1][ $y - 1]; } // Return maximum number of 1s after flipping a submatrix function sol( $mat ) { global $C , $R ; $ans = 0; // Precomputing the number of 1s $ones = array_fill (0, $R + 1, array_fill (0, $C + 1,0)); for ( $i = 1; $i <= $R ; $i ++) for ( $j = 1; $j <= $C ; $j ++) $ones [ $i ][ $j ] = $ones [ $i - 1][ $j ] + $ones [ $i ][ $j - 1] - $ones [ $i - 1][ $j - 1] + (int)( $mat [ $i - 1][ $j - 1] == 1); // Finding the maximum number of 1s after flipping for ( $k = 1; $k <= min( $R , $C ); $k ++) for ( $i = 1; $i + $k - 1 <= $R ; $i ++) for ( $j = 1; $j + $k - 1 <= $C ; $j ++) $ans = max( $ans , ( $ones [ $R ][ $C ] + $k * $k - 2 * cal( $ones , $i , $j , $k ))); return $ans ; } // Driver code $mat = array ( array (0, 0, 1), array ( 0, 0, 1), array ( 1, 0, 1 )); echo sol( $mat ); // This code is contributed by mits ?> |
Javascript
<script> // Javascript program to find maximum number of ones after // one flipping in Binary Matrix let R = 3; let C = 3 ; // Return number of ones in square submatrix of size // k x k starting from (x, y) function cal(ones, x, y, k) { return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1] - ones[x + k - 1][y - 1] + ones[x - 1][y - 1]; } // Return maximum number of 1s after flipping a submatrix function sol(mat) { let ans = 0; let val =0; // Precomputing the number of 1s let ones = new Array(R + 1); // Loop to create 2D array using 1D array for ( var i = 0; i < ones.length; i++) { ones[i] = new Array(2); } for ( var i = 0; i < ones.length; i++) { for ( var j = 0; j < ones.length; j++) { ones[i][j] = 0; } } for (let i = 1; i <= R; i++) for (let j = 1; j <= C; j++) { if (mat[i - 1][j - 1] == 1) val=1; ones[i][j] = ones[i - 1][j] + ones[i][j - 1] - ones[i - 1][j - 1] + (val); } // Finding the maximum number of 1s after flipping for (let k = 1; k <= Math.min(R, C); k++) for (let i = 1; i + k - 1 <= R; i++) for (let j = 1; j + k - 1 <= C; j++) ans = Math.max(ans, (ones[R][C] + k * k - 2 * cal(ones, i, j, k))); return ans; } // driver function let mat = [[0, 0, 1], [ 0, 0, 1], [ 1, 0, 1 ] ]; document.write(sol(mat)); // This code is contributed by susmitakundugoaldanga. </script> |
8
Time Complexity: O(R*C*min(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.