Find pair of rows in a binary matrix that has maximum bit difference

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 matrixconst int MAX = 100;Â
struct TrieNode{  int leaf; //store index of visited row  struct TrieNode *Child[2];};Â
// Utility function to create a new Trie nodeTrieNode * getNode(){Â Â TrieNode * newNode = new TrieNode;Â Â newNode->leaf = 0;Â Â newNode->Child[0] = newNode->Child[1] = NULL;Â Â return newNode;}Â
// utility function insert new row in trievoid 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 matrixpair<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 rowvoid 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 programint 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 libraryimport 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 matrixMAX = 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 nodedef getNode():Â Â Â Â newNode = TrieNode()Â Â Â Â newNode.leaf = 0Â Â Â Â newNode.Child = [None] * 2Â Â Â Â return newNodeÂ
# utility function insert new row in triedef 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 matrixdef 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 rowdef 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 programif __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 differenceusing 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 matrixconst MAX = 100;Â
class TrieNode {  constructor() {    this.leaf = 0; // store index of visited row    this.Child = [null, null];  }}Â
// Utility function to create a new Trie nodefunction getNode() {Â Â const newNode = new TrieNode();Â Â newNode.leaf = 0;Â Â newNode.Child = [null, null];Â Â return newNode;}Â
// utility function insert new row in triefunction 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 matrixfunction 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 rowfunction 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 programconst mat = [  [0, 1, 0, 1, 0],  [1, 0, 1, 1, 0],  [0, 0, 1, 0, 1]];maxDiff(mat, 3, 5); |
Output
(1, 3)
Time Complexity:O(n)
Auxiliary Space: O(n)
If you like zambiatek and would like to contribute, you can also write an article using write.zambiatek.com or mail your article to review-team@zambiatek.com. See your article appearing on the zambiatek main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



