Print unique rows in a given Binary matrix


In computer science, binary matrix holds a very strong position containing a lot of information as the data is depicted using 0’s and 1’s which is the language of computers. In binary matrix, unique row refers to a row that is not identical to any other row in the matrix. Each unique row contains unique information that is not present anywhere else in the matrix except the row itself. Discovering these unique rows give information about relationships between rows, patterns in the matrix and identification of critical elements.

Problem Statement

Given a binary matrix mat[] containing 0’s and 1’s. The task is to print all the unique rows of the matrix.

Sample Example 1

Input

mat[][] = 
{{1, 0, 1, 1, 0},
{0, 1, 0, 0, 0},
{1, 0, 1, 1, 0},
{0, 1, 0, 0, 1}}

Output

1 0 1 1 0
0 1 0 0 0
0 1 0 0 1

Explanation

In the given matrix, row1 = 1 0 1 1 0
row2 = 0 1 0 0 0
row3 = 1 0 1 1 0
row4 = 0 1 0 0 1
Since, row1 = row3 so unique rows are row1, row2 and row4.

Sample Example 2

Input

mat[][] = 
{{1, 0, 1, 1, 0},
{1, 0, 1, 1, 0},
{1, 0, 1, 1, 0},
{1, 0, 1, 1, 0}}

Output

1 0 1 1 0

Explanation

In the given matrix, row1 = 1 0 1 1 0
row2 = 1 0 1 1 0
row3 = 1 0 1 1 0
row4 = 1 0 1 1 01

Since all rows are equal so the unique row is row1.

Approach 1: Brute Force Approach

Brute force solution for the problem is to first print the first row of the matrix and then for each row check with the previous rows to check for duplicacy.

Pseudocode

function uniqueRows(mat: boolean[row][col], i: integer) -> boolean
   flag <- false    
   for j from 0 to i - 1
      flag <- true        
      for k from 0 to col
         if mat[i][k] ≠ mat[j][k]
            flag <- false
            exit loop            
      if flag = true
         break loop    
   return flag

Example: C++ Implementation

The following code prints the unique rows in a binary matrix.

#include <bits/stdc++.h>
using namespace std;
#define row 4
#define col 5

// Function used to determine if a row is unique or not
bool uniqueRows(bool mat[row][col], int i){
   bool flag = 0;
   for (int j = 0; j < i; j++){
      flag = 1;
      for (int k = 0; k <= col; k++)
         if (mat[i][k] != mat[j][k])
            flag = 0;
      if (flag == 1)
         break;
   }
   return flag;
}
int main(){
   bool mat[row][col] = {{1, 0, 1, 1, 0},
      {0, 1, 0, 0, 0},
      {1, 0, 1, 1, 0},
      {0, 1, 0, 0, 1}};
   for (int i = 0; i < row; i++) {
      if (!uniqueRows(mat, i)) {
         for (int j = 0; j < col; j++) {
            cout << mat[i][j] << " ";
         }
         cout << endl;
      }
   }
   return 0;
}

Output

1 0 1 1 0 
0 1 0 0 0 
0 1 0 0 1

Time Complexity − O(col * row^2)

Space Complexity − O(1)

Approach 2: Using Trie

The approach while using a trie data structure is to insert each row into the trie having alphabet size of 2. If the row is seen before, do not print it else print a new unique row.

Pseudocode

struct Trie
   leaf: boolean
   c: array of Trie pointers

function newNode() -> Trie pointer
   node <- new Trie
   node.c <- array of Trie pointers with size 2
   node.c[0] <- null
   node.c[1] <- null
   node.leaf <- false
   return node

function insert(head: reference to Trie pointer, arr: array of booleans) -> boolean
   ptr <- head
   for i from 0 to col - 1
      if ptr.c[arr[i]] = null
         ptr.c[arr[i]] <- newNode()
      ptr <- ptr.c[arr[i]]
   if ptr.leaf = true
      return false
   ptr.leaf <- true
   return true

Example: C++ Implementation

The following code prints the unique rows in a binary matrix.

#include <iostream>
using namespace std;
#define row 4
#define col 5
// Structure of trie
struct Trie {
   bool leaf;
   Trie *c[2];
};
// function to create new trie node
Trie *newNode(){
   Trie *node = new Trie;
   node->c[0] = node->c[1] = nullptr;
   node->leaf = false;
   return node;
}
// Function to insert elements of matrix to trie
bool insert(Trie *&head, bool *arr){
   Trie *ptr = head;
   for (int i = 0; i < col; i++) {
      if (ptr->c[arr[i]] == nullptr) {
         ptr->c[arr[i]] = newNode();
      }
      ptr = ptr->c[arr[i]];
   }
   // row inserted before
   if (ptr->leaf) {
      return false;
   }
   // new unique row; mark leaf node
   return ptr->leaf = true;
}
int main(){
   bool mat[row][col] = {{1, 0, 1, 1, 0},
      {0, 1, 0, 0, 0},
      {1, 0, 1, 1, 0},
      {0, 1, 0, 0, 1}};
   Trie *head = newNode();
   for (int i = 0; i < row; i++) {
      if (insert(head, mat[i])) {
         for (int j = 0; j < col; j++) {
            cout << mat[i][j] << " ";
         }
         cout << endl;
      }
   }
   return 0;
}

Output

1 0 1 1 0 
0 1 0 0 0 
0 1 0 0 1

Time Complexity − O(col * row)

Space Complexity − O(col * row)

Approach 3: Decimal

The approach is to convert each of the row in out input matrix to a decimal number. The task left at our hand will be to compare all the decimals and remove all duplicates and print the unique pairs.

Pseudocode

function uniqueRow(mat: boolean[row][col], i: integer, set: unordered_set of integers) -> boolean
   decimal <- 0
   flag <- false    
   for j from 0 to col - 1
      decimal <- decimal + mat[i][j] * 2^j    
   if decimal is in set
      flag <- false
   else
      flag <- true
      insert decimal into set    
   return flag

Example: C++ Implementation

The following code prints the unique rows in a binary matrix.

#include <iostream>
#include <vector>
#include <unordered_set>
#include <cmath>
using namespace std;
#define row 4
#define col 5

// Function to find the unique row in the matrix
bool uniqueRow(bool mat[row][col], int i, unordered_set<unsigned> &set){
   unsigned decimal = 0;
   bool flag;
   for (int j = 0; j < col; j++){
      // Decimal equivalent
      decimal += mat[i][j] * pow(2, j);
   }
   // Duplicate row
   if (set.find(decimal) != set.end()){
      flag = 0;
   }
   // Unique row
   else {
      flag = 1;
      set.insert(decimal);
   }
   return flag;
}
int main() {
   bool mat[row][col] = {{1, 0, 1, 1, 0},
      {0, 1, 0, 0, 0},
      {1, 0, 1, 1, 0},
      {0, 1, 0, 0, 1}};
   unordered_set<unsigned> set;
   for (int i = 0; i < row; i++) {
      if (uniqueRow(mat, i, set)) {
         for (int j = 0; j < col; j++) {
            cout << mat[i][j] << " ";
         }
         cout << endl;
      }
   }
   return 0;
}

Output

1 0 1 1 0 
0 1 0 0 0 
0 1 0 0 1

Time Complexity − O(col * row)

Space Complexity − O(col)

Conclusion

In conclusion, the given solutions and codes give efficient solution to identify and print unique rows in a binary matrix. This problem has practical implementations in domains like data analysis and pattern recognition.

Updated on: 03-Nov-2023

167 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements