Given a Binary Matrix. The task is to find the pair of row in the Binary matrix that has maximum bit difference Examples:
Input: mat[][] = {{1, 1, 1, 1}, {1, 1, 0, 1}, {0, 0, 0, 0}}; Output : (1, 3) Bit difference between row numbers 1 and 3 is maximum with value 4. Bit difference between 1 and 2 is 1 and between 2 and 3 is 3. Input: mat[][] = {{1 ,1 ,1 ,1 } {1 ,0, 1 ,1 } {0 ,1 ,0 ,0 } {0, 0 ,0 ,0 }} Output : (2, 3) Bit difference between rows 2 and 3 is maximum which is 4. Input: mat[][] = {{1 ,0 ,1 ,1 } {1 ,1 ,1 ,1 } {0 ,1 ,0 ,1 } {1, 0 ,0 ,0 }} Output : (1, 3) or (2 ,4 ) or (3 ,4 ) They all are having maximum bit difference that is 3
Simple solution of this problem is that pick each row of binary matrix one -by -one and compute maximum bit difference with rest of the rows of matrix .at last return rows those have maximum bit difference .Â
An Efficient solution using Trie Data Structure. Below is algorithm.
1). Create an empty Trie. Every node of Trie contains two children for 0 and 1 bits. 2). Insert First Row of Binary matrix into Trie 3).Traverse rest of the rows of given Binary Matrix a). For Each Row First we search maximum bit difference with rows that we insert before that in Trie and count bit difference b). For every search we update maximum bit_diff count if needed else not store pair of index that have maximum bit difference c). At Last Print Pair
Implementation:
CPP
// C++ program to Find Pair of row in Binary matrix // that has maximum Bit difference #include<bits/stdc++.h> using namespace std; Â
// Maximum size of matrix const int MAX = 100; Â
struct TrieNode {   int leaf; //store index of visited row   struct TrieNode *Child[2]; }; Â
// Utility function to create a new Trie node TrieNode * getNode() { Â Â TrieNode * newNode = new TrieNode; Â Â newNode->leaf = 0; Â Â newNode->Child[0] = newNode->Child[1] = NULL; Â Â return newNode; } Â
// utility function insert new row in trie void insert(TrieNode *root, int Mat[][MAX], int n, Â Â Â Â Â Â int row_index) { Â Â TrieNode * temp = root; Â
  for ( int i=0; i<n; i++)   {     // Add a new Node into trie     if (temp->Child[ Mat[row_index][i] ] == NULL)       temp->Child[ Mat[row_index][i] ] = getNode(); Â
    // move current node to point next node in trie     temp = temp->Child[ Mat[row_index][i] ];   } Â
  // store index of currently inserted row   temp->leaf = row_index +1 ; } Â
// utility function calculate maximum bit difference of // current row with previous visited row of binary matrix pair< int , int > maxBitDiffCount(TrieNode * root, Â Â Â Â Â Â Â Â int Mat[][MAX], int n, int row_index) { Â Â TrieNode * temp = root; Â Â int count = 0; Â
  // Find previous visited row of binary matrix   // that has starting bit same as current row   for ( int i= 0 ; i < n ; i++)   {     // First look for same bit in trie     if (temp->Child[ Mat[row_index][i] ] != NULL)       temp = temp->Child[ Mat[row_index][i] ]; Â
    // Else looking for opposite bit     else if (temp->Child[1 - Mat[row_index][i]] != NULL)     {       temp = temp->Child[1- Mat[row_index][i]];       count++;     }   } Â
  int leaf_index = temp->leaf;   int count1 = 0 ;   temp = root; Â
  // Find previous visited row of binary matrix   // that has starting bit opposite to current row   for ( int i= 0 ; i < n ; i++)   {     // First looking for opposite bit     if (temp->Child[ 1 - Mat[row_index][i] ] !=NULL)     {       temp = temp->Child[ 1- Mat[row_index][i] ];       count1++;     } Â
    // Else look for same bit in trie     else if (temp->Child[ Mat[row_index][i] ] != NULL)       temp = temp->Child[ Mat[row_index][i] ];   } Â
  pair < int , int > P = count1 > count ?             make_pair(count1, temp->leaf):             make_pair(count, leaf_index); Â
  // return pair that contain both bit difference   // count and index of row with we get bit   // difference   return P; } Â
// Returns maximum bit difference pair of row void maxDiff( int mat[][MAX], int n, int m) { Â Â TrieNode * root = getNode(); Â
  // Insert first matrix row in trie   insert(root, mat, m, 0); Â
  int max_bit_diff = INT_MIN;   pair < int , int > P, temp ; Â
  // Traverse all rest row of binary matrix   for ( int i = 1 ; i < n; i++)   {     // compute bit difference with previous visited     // rows of matrix     temp = maxBitDiffCount(root, mat, m ,i); Â
    // update maximum bit difference     if (max_bit_diff < temp.first )     {       max_bit_diff = temp.first;       P = make_pair( temp.second, i+1);     } Â
    // insert current row value into Trie     insert(root, mat, m, i );   } Â
  // print maximum bit difference pair in row   cout << "(" << P.first << ", " << P.second << ")" ; } Â
// Driver program int main() { Â Â int mat[][MAX] = {{0 ,1 ,0 ,1, 0 }, Â Â Â Â {1, 0, 1 ,1 ,0 }, Â Â Â Â {0 ,0 ,1 ,0, 1 } Â Â }; Â Â maxDiff(mat, 3, 5) ; Â Â return 0; } |
Java
// Importing required library import java.util.*; class Pair {     int first,second;     Pair( int first, int second)     {         this .first = first;         this .second = second;     } } public class Main {     // Maximum size of matrix     static final int MAX = 100 ; Â
    static class TrieNode {         int leaf; // store index of visited row         TrieNode[] Child = new TrieNode[ 2 ]; Â
        // Constructor         TrieNode() {             this .leaf = 0 ;             this .Child[ 0 ] = null ;             this .Child[ 1 ] = null ;         }     } Â
    // Utility function to create a new Trie node     static TrieNode getNode() {         TrieNode newNode = new TrieNode();         return newNode;     } Â
    // utility function insert new row in trie     static void insert(TrieNode root, int [][] Mat, int n, int row_index) {         TrieNode temp = root; Â
        for ( int i = 0 ; i < n; i++) {             // Add a new Node into trie             if (temp.Child[(Mat[row_index][i])] == null )                 temp.Child[(Mat[row_index][i])] = getNode(); Â
            // move current node to point next node in trie             temp = temp.Child[(Mat[row_index][i])];         } Â
        // store index of currently inserted row         temp.leaf = row_index + 1 ;     } Â
    // utility function calculate maximum bit difference of     // current row with previous visited row of binary matrix     static Pair maxBitDiffCount(TrieNode root, int [][] Mat, int n, int row_index) {         TrieNode temp = root;         int count = 0 ; Â
        // Find previous visited row of binary matrix         // that has starting bit same as current row         for ( int i = 0 ; i < n; i++) {             // First look for same bit in trie             if (temp.Child[(Mat[row_index][i])] != null )                 temp = temp.Child[(Mat[row_index][i])]; Â
                // Else looking for opposite bit             else if (temp.Child[ 1 - Mat[row_index][i]] != null ) {                 temp = temp.Child[ 1 - Mat[row_index][i]];                 count++;             }         } Â
        int leaf_index = temp.leaf;         int count1 = 0 ;         temp = root; Â
        // Find previous visited row of binary matrix         // that has starting bit opposite to current row         for ( int i = 0 ; i < n; i++) {             // First looking for opposite bit             if (temp.Child[ 1 - Mat[row_index][i]] != null ) {                 temp = temp.Child[ 1 - Mat[row_index][i]];                 count1++;             } Â
            // Else look for same bit in trie             else if (temp.Child[(Mat[row_index][i])] != null )                 temp = temp.Child[(Mat[row_index][i])];         } Â
        Pair P = count1 > count ?                 new Pair(count1, temp.leaf) :                 new Pair(count, leaf_index); Â
        // return pair that contain both bit difference         // count and index of row with we get bit         // difference         return P;     } Â
    // Returns maximum bit difference pair of row     static void maxDiff( int [][] mat, int n, int m) {         TrieNode root = getNode(); Â
        // Insert first matrix row in trie         insert(root, mat, m, 0 ); Â
        int max_bit_diff = Integer.MIN_VALUE;         Pair P= null ;Pair temp= null ; Â
        // Traverse all rest row of binary matrix         for ( int i = 1 ; i < n; i++) {             // compute bit difference with previous visited             // rows of matrix             temp = maxBitDiffCount(root, mat, m, i); Â
            // update maximum bit difference             if (max_bit_diff < temp.first) {                 max_bit_diff = temp.first;                 P = new Pair(temp.second, i + 1 );             } Â
            // insert current row value into Trie             insert(root, mat, m, i);         }         System.out.println( "(" +P.first+ ", " +P.second+ ")" );     } Â
    public static void main(String[] args) {         int mat[][] = {{ 0 , 1 , 0 , 1 , 0 },             { 1 , 0 , 1 , 1 , 0 },             { 0 , 0 , 1 , 0 , 1 }         };         maxDiff(mat, 3 , 5 ) ;     } } |
Python3
import sys Â
# Maximum size of matrix MAX = 100 Â
class TrieNode:     def __init__( self ):         self .leaf = 0  # store index of visited row         self .Child = [ None ] * 2 Â
# Utility function to create a new Trie node def getNode(): Â Â Â Â newNode = TrieNode() Â Â Â Â newNode.leaf = 0 Â Â Â Â newNode.Child = [ None ] * 2 Â Â Â Â return newNode Â
# utility function insert new row in trie def insert(root, Mat, n, row_index): Â Â Â Â temp = root Â
    for i in range (n):         # Add a new Node into trie         if temp.Child[(Mat[row_index][i])] = = None :             temp.Child[(Mat[row_index][i])] = getNode() Â
        # move current node to point next node in trie         temp = temp.Child[(Mat[row_index][i])] Â
    # store index of currently inserted row     temp.leaf = row_index + 1 Â
# utility function calculate maximum bit difference of # current row with previous visited row of binary matrix def maxBitDiffCount(root, Mat, n, row_index):     temp = root     count = 0 Â
    # Find previous visited row of binary matrix     # that has starting bit same as current row     for i in range (n):         # First look for same bit in trie         if temp.Child[(Mat[row_index][i])] ! = None :             temp = temp.Child[(Mat[row_index][i])] Â
        # Else looking for opposite bit         elif temp.Child[ 1 - Mat[row_index][i]] ! = None :             temp = temp.Child[ 1 - Mat[row_index][i]]             count + = 1 Â
    leaf_index = temp.leaf     count1 = 0     temp = root Â
    # Find previous visited row of binary matrix     # that has starting bit opposite to current row     for i in range (n):         # First looking for opposite bit         if temp.Child[ 1 - Mat[row_index][i]] ! = None :             temp = temp.Child[ 1 - Mat[row_index][i]]             count1 + = 1 Â
        # Else look for same bit in trie         elif temp.Child[(Mat[row_index][i])] ! = None :             temp = temp.Child[(Mat[row_index][i])] Â
    P = (count1, temp.leaf) if count1 > count else (count, leaf_index) Â
    # return pair that contain both bit difference     # count and index of row with we get bit     # difference     return P Â
# Returns maximum bit difference pair of row def maxDiff(mat, n, m): Â Â Â Â root = getNode() Â
    # Insert first matrix row in trie     insert(root, mat, m, 0 ) Â
    max_bit_diff = - sys.maxsize     P, temp = None , None Â
    # Traverse all rest row of binary matrix     for i in range ( 1 , n):         # compute bit difference with previous visited         # rows of matrix         temp = maxBitDiffCount(root, mat, m, i) Â
        # update maximum bit difference         if max_bit_diff < temp[ 0 ]:             max_bit_diff = temp[ 0 ]             P = (temp[ 1 ], i + 1 ) Â
        # insert current row value into Trie         insert(root, mat, m, i) Â
    # print maximum bit difference pair in row     print (f "({P[0]}, {P[1]})" ) Â
# Driver program if __name__ = = "__main__" : Â Â Â Â mat = [[ 0 , 1 , 0 , 1 , 0 ], Â Â Â Â [ 1 , 0 , 1 , 1 , 0 ], Â Â Â Â [ 0 , 0 , 1 , 0 , 1 ] Â Â Â Â ] Â Â Â Â maxDiff(mat, 3 , 5 ) Â
# This code is contributed by Prince Kumar |
C#
// C# program to Find Pair of row in Binary matrix // that has maximum Bit difference using System; Â
public class TrieNode {   public int Leaf; //store index of visited row   public TrieNode[] Child; Â
  public TrieNode()   {     Leaf = 0;     Child = new TrieNode[2];     Child[0] = Child[1] = null ;   } } Â
public class MaxBitDifference {   // Maximum size of matrix   private const int MAX = 100;   // Utility function to create a new Trie node   private static TrieNode GetNode()   {     return new TrieNode();   } Â
  // utility function insert new row in trie   private static void Insert(TrieNode root, int [,] mat, int n, int rowIndex)   {     var temp = root; Â
    for ( var i = 0; i < n; i++)     { Â
      // Add a new Node into trie       if (temp.Child[(mat[rowIndex, i])] == null )       {         temp.Child[(mat[rowIndex, i])] = GetNode();       } Â
      // move current node to point next node in trie       temp = temp.Child[(mat[rowIndex, i])];     } Â
    // store index of currently inserted row     temp.Leaf = rowIndex + 1;   } Â
  // utility function calculate maximum bit difference of   // current row with previous visited row of binary matrix   private static Tuple< int , int > MaxBitDiffCount(TrieNode root, int [,] mat, int n, int rowIndex)   {     var temp = root;     var count = 0; Â
    // Find previous visited row of binary matrix     // that has starting bit same as current row     for ( var i = 0; i < n; i++)     { Â
      // First look for same bit in trie       if (temp.Child[(mat[rowIndex, i])] != null )       {         temp = temp.Child[(mat[rowIndex, i])];       } Â
      // Else looking for opposite bit       else if (temp.Child[1 - mat[rowIndex, i]] != null )       {         temp = temp.Child[1 - mat[rowIndex, i]];         count++;       }     } Â
    var leafIndex = temp.Leaf;     var count1 = 0;     temp = root; Â
    // Find previous visited row of binary matrix     // that has starting bit opposite to current row     for ( var i = 0; i < n; i++)     { Â
      // First looking for opposite bit       if (temp.Child[1 - mat[rowIndex, i]] != null )       {         temp = temp.Child[1 - mat[rowIndex, i]];         count1++;       } Â
      // Else look for same bit in trie       else if (temp.Child[(mat[rowIndex, i])] != null )       {         temp = temp.Child[(mat[rowIndex, i])];       }     } Â
    var P = count1 > count ? new Tuple< int , int >(count1, temp.Leaf) : new Tuple< int , int >(count, leafIndex); Â
    // return pair that contain both bit difference     // count and index of row with we get bit     // difference     return P;   } Â
  // Returns maximum bit difference pair of row   public static void MaxDiff( int [,] mat, int n, int m)   {     var root = GetNode(); Â
    // Insert first matrix row in trie     Insert(root, mat, m, 0); Â
    var maxBitDiff = int .MinValue;     Tuple< int , int > P = null , temp = null ; Â
    // Traverse all rest row of binary matrix     for ( var i = 1; i < n; i++)     { Â
      // compute bit difference with previous visited       // rows of matrix       temp = MaxBitDiffCount(root, mat, m, i); Â
      // update maximum bit difference       if (maxBitDiff < temp.Item1)       {         maxBitDiff = temp.Item1;         P = new Tuple< int , int >(temp.Item2, i + 1);       } Â
      // insert current row value into Trie       Insert(root, mat, m, i);     } Â
    // print maximum bit difference pair in row     Console.WriteLine( "({0}, {1})" , P.Item1, P.Item2);   } Â
  // Driver program   public static void Main()   {     var mat = new int [3, 5] {{0, 1, 0, 1, 0}, {1, 0, 1, 1, 0}, {0, 0, 1, 0, 1}};     MaxDiff(mat, 3, 5);   } } |
Javascript
// Maximum size of matrix const MAX = 100; Â
class TrieNode {   constructor() {     this .leaf = 0; // store index of visited row     this .Child = [ null , null ];   } } Â
// Utility function to create a new Trie node function getNode() { Â Â const newNode = new TrieNode(); Â Â newNode.leaf = 0; Â Â newNode.Child = [ null , null ]; Â Â return newNode; } Â
// utility function insert new row in trie function insert(root, Mat, n, row_index) { Â Â let temp = root; Â
  for (let i = 0; i < n; i++) {     // Add a new Node into trie     if (temp.Child[(Mat[row_index][i])] == null ) {       temp.Child[(Mat[row_index][i])] = getNode();     } Â
    // move current node to point next node in trie     temp = temp.Child[(Mat[row_index][i])];   } Â
  // store index of currently inserted row   temp.leaf = row_index + 1; } Â
// utility function calculate maximum bit difference of // current row with previous visited row of binary matrix function maxBitDiffCount(root, Mat, n, row_index) { Â Â let temp = root; Â Â let count = 0; Â
  // Find previous visited row of binary matrix   // that has starting bit same as current row   for (let i = 0; i < n; i++) {     // First look for same bit in trie     if (temp.Child[(Mat[row_index][i])] != null ) {       temp = temp.Child[(Mat[row_index][i])];     } Â
    // Else looking for opposite bit     else if (temp.Child[1 - Mat[row_index][i]] != null ) {       temp = temp.Child[1 - Mat[row_index][i]];       count += 1;     }   } Â
  let leaf_index = temp.leaf;   let count1 = 0;   temp = root; Â
  // Find previous visited row of binary matrix   // that has starting bit opposite to current row   for (let i = 0; i < n; i++) {     // First looking for opposite bit     if (temp.Child[1 - Mat[row_index][i]] != null ) {       temp = temp.Child[1 - Mat[row_index][i]];       count1 += 1;     } Â
    // Else look for same bit in trie     else if (temp.Child[(Mat[row_index][i])] != null ) {       temp = temp.Child[(Mat[row_index][i])];     }   } Â
  let P = count1 > count ? [count1, temp.leaf] : [count, leaf_index]; Â
  // return pair that contain both bit difference   // count and index of row with we get bit   // difference   return P; } Â
// Returns maximum bit difference pair of row function maxDiff(mat, n, m) { Â Â const root = getNode(); Â
  // Insert first matrix row in trie   insert(root, mat, m, 0); Â
  let max_bit_diff = -Infinity;   let P = null ;   let temp = null ; Â
  // Traverse all rest row of binary matrix   for (let i = 1; i < n; i++) {     // compute bit difference with previous visited     // rows of matrix     temp = maxBitDiffCount(root, mat, m, i); Â
    // update maximum bit difference     if (max_bit_diff < temp[0]) {       max_bit_diff = temp[0];       P = [temp[1], i + 1];     } Â
    // insert current row value into Trie     insert(root, mat, m, i);   } Â
  // print maximum bit difference pair in row   console.log(`(${P[0]}, ${P[1]})`); } Â
// Driver program const mat = [ Â Â [0, 1, 0, 1, 0], Â Â [1, 0, 1, 1, 0], Â Â [0, 0, 1, 0, 1] ]; maxDiff(mat, 3, 5); |
(1, 3)
Time Complexity:O(n)
Auxiliary Space: O(n)
If you like neveropen 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 neveropen main page and help other Geeks.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!