Print unique rows in a given boolean matrix

Given a binary matrix, print all unique rows of the given matrix. 

Example: 

Input:
        {0, 1, 0, 0, 1}
        {1, 0, 1, 1, 0}
        {0, 1, 0, 0, 1}
        {1, 1, 1, 0, 0}
Output:
    0 1 0 0 1 
    1 0 1 1 0 
    1 1 1 0 0 
Explanation: 
The rows are r1={0, 1, 0, 0, 1}, 
r2={1, 0, 1, 1, 0}, r3={0, 1, 0, 0, 1}, 
r4={1, 1, 1, 0, 0}, As r1 = r3, remove r3
and print the other rows.

Input:
        {0, 1, 0}
        {1, 0, 1}
        {0, 1, 0}
Output:
   0 1 0
   1 0 1
Explanation: 
The rows are r1={0, 1, 0}, 
r2={1, 0, 1}, r3={0, 1, 0} As r1 = r3,
remove r3 and print the other rows.

Method 1: This method explains the simple approach towards solving the above problem. 

Approach: A simple approach would be to check each row with all processed rows. Print the first row. Now, starting from the second row, for each row, compare the row with already processed rows. If the row matches with any of the processed rows, skip it else print it.

Algorithm: 



  1. Traverse the matrix row-wise
  2. For each row check if there is any similar row less than the current index.
  3. If any two rows are similar then do not print the row.
  4. Else print the row.

Implementation: 

filter_none

edit
close

play_arrow

link
brightness_4
code

// Given a binary matrix of M X N of integers, 
// you need to return only unique rows of binary array 
#include <bits/stdc++.h>
using namespace std;
#define ROW 4 
#define COL 5 
  
// The main function that prints 
// all unique rows in a given matrix.
void findUniqueRows(int M[ROW][COL])
{
    //Traverse through the matrix
    for(int i=0; i<ROW; i++)
    {
        int flag=0;
          
        //check if there is similar column
        //is already printed, i.e if i and 
        //jth column match.
        for(int j=0; j<i; j++)
        {
            flag=1;
              
            for(int k=0; k<=COL; k++)
            if(M[i][k]!=M[j][k])
                flag=0;
              
            if(flag==1)
            break;
        }
          
        //if no row is similar
        if(flag==0)
        {
            //print the row
            for(int j=0; j<COL; j++)
                cout<<M[i][j]<<" ";
            cout<<endl;
        }
    }
}
  
// Driver Code
int main() 
    int M[ROW][COL] = {{0, 1, 0, 0, 1}, 
                       {1, 0, 1, 1, 0}, 
                       {0, 1, 0, 0, 1}, 
                       {1, 0, 1, 0, 0}}; 
  
    findUniqueRows(M); 
  
    return 0; 
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Given a binary matrix of M X N 
// of integers, you need to return
// only unique rows of binary array  
class GFG{
      
static int ROW = 4;
static int COL = 5;
  
// Function that prints all 
// unique rows in a given matrix.
static void findUniqueRows(int M[][])
{
      
    // Traverse through the matrix
    for(int i = 0; i < ROW; i++)
    {
        int flag = 0;
          
        // Check if there is similar column
        // is already printed, i.e if i and
        // jth column match.
        for(int j = 0; j < i; j++) 
        {
            flag = 1;
  
            for(int k = 0; k < COL; k++)
                if (M[i][k] != M[j][k])
                    flag = 0;
  
            if (flag == 1)
                break;
        }
  
        // If no row is similar
        if (flag == 0)
        {
              
            // Print the row
            for(int j = 0; j < COL; j++)
                System.out.print(M[i][j] + " ");
  
            System.out.println();
        }
    }
}
  
// Driver Code
public static void main(String[] args)
{
    int M[][] = { { 0, 1, 0, 0, 1 },
                  { 1, 0, 1, 1, 0 },
                  { 0, 1, 0, 0, 1 },
                  { 1, 0, 1, 0, 0 } };
  
    findUniqueRows(M);
}
}
  
// This code is contributed by mark_85
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Given a binary matrix of M X N of
# integers, you need to return only
# unique rows of binary array
ROW = 4
COL = 5
  
# The main function that prints
# all unique rows in a given matrix.
def findUniqueRows(M):
      
    # Traverse through the matrix
    for i in range(ROW):
        flag = 0
  
        # Check if there is similar column
        # is already printed, i.e if i and
        # jth column match.
        for j in range(i):
            flag = 1
  
            for k in range(COL):
                if (M[i][k] != M[j][k]):
                    flag = 0
  
            if (flag == 1):
                break
  
        # If no row is similar
        if (flag == 0):
              
            # Print the row
            for j in range(COL):
                print(M[i][j], end = " ")
                  
            print()    
  
# Driver Code
if __name__ == '__main__':
      
    M = [ [ 0, 1, 0, 0, 1 ],
          [ 1, 0, 1, 1, 0 ],
          [ 0, 1, 0, 0, 1 ],
          [ 1, 0, 1, 0, 0 ] ]
  
    findUniqueRows(M)
  
# This code is contributed by mohit kumar 29
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Given a binary matrix of M X N  
// of integers, you need to return 
// only unique rows of binary array   
using System;
  
class GFG{
      
static int ROW = 4; 
static int COL = 5; 
    
// Function that prints all  
// unique rows in a given matrix. 
static void findUniqueRows(int[,] M) 
      
    // Traverse through the matrix 
    for(int i = 0; i < ROW; i++) 
    
        int flag = 0; 
            
        // Check if there is similar column 
        // is already printed, i.e if i and 
        // jth column match. 
        for(int j = 0; j < i; j++)  
        
            flag = 1; 
              
            for(int k = 0; k < COL; k++) 
                if (M[i, k] != M[j, k]) 
                    flag = 0; 
    
            if (flag == 1) 
                break
        
    
        // If no row is similar 
        if (flag == 0) 
        
              
            // Print the row 
            for(int j = 0; j < COL; j++) 
                Console.Write(M[i, j] + " "); 
    
            Console.WriteLine(); 
        
    
  
// Driver code
static void Main() 
{
    int[,] M = { { 0, 1, 0, 0, 1 }, 
                 { 1, 0, 1, 1, 0 }, 
                 { 0, 1, 0, 0, 1 }, 
                 { 1, 0, 1, 0, 0 } }; 
      
    findUniqueRows(M); 
}
}
  
// This code is contributed by divyeshrabadiya07
chevron_right

Output: 

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

Complexity Analysis: 

Method 2: This method uses Binary Search Tree to solve the above operation. The Binary Search Tree is a node-based binary tree data structure which has the following properties: 

The above properties of Binary Search Tree provide ordering among keys so that the operations like search, minimum and maximum can be done fast. If there is no order, then we may have to compare every key to search a given key.

Approach: The process must begin from finding the decimal equivalent of each row and inserting them into a BST. As we know, each node of the BST will contain two fields, one field for the decimal value, other for row number. One must not insert a node if it is duplicated. Finally, traverse the BST and print the corresponding rows.

Algorithm: 

  1. Create a BST in which no duplicate elements can be stored. Create a function to convert a row into decimal and to convert the decimal value into binary array.
  2. Traverse through the matrix and insert the row into the BST.
  3. Traverse the BST (inorder traversal) and convert the decimal into binary array and print it.

Implementation: 



filter_none

edit
close

play_arrow

link
brightness_4
code

// Given a binary matrix of M X N of integers, 
// you need to return only unique rows of binary array 
#include <bits/stdc++.h>
using namespace std;
#define ROW 4 
#define COL 5 
  
class BST 
    int data; 
    BST *left, *right; 
  
    public
      
    // Default constructor. 
    BST(); 
      
    // Parameterized constructor. 
    BST(int); 
      
    // Insert function. 
    BST* Insert(BST *, int); 
      
    // Inorder traversal. 
    void Inorder(BST *); 
}; 
  
//convert array to decimal
int convert(int arr[])
{
    int sum=0;
      
    for(int i=0; i<COL; i++)
    {
        sum+=pow(2,i)*arr[i];
    }
    return sum;
}
  
//print the column represented as integers
void print(int p)
{
    for(int i=0; i<COL; i++)
    {
        cout<<p%2<<" ";
        p/=2;
    }
    cout<<endl;
}
  
  
// Default Constructor definition. 
BST :: BST() : data(0), left(NULL), right(NULL){} 
  
// Parameterized Constructor definition. 
BST :: BST(int value) 
    data = value; 
    left = right = NULL; 
  
// Insert function definition. 
BST* BST :: Insert(BST *root, int value) 
    if(!root) 
    
        // Insert the first node, if root is NULL. 
        return new BST(value); 
    
      
    //if the value is present
    if(value == root->data)
     return root;
  
    // Insert data. 
    if(value > root->data) 
    
        // Insert right node data, if the 'value' 
        // to be inserted is greater than 'root' node data. 
          
        // Process right nodes. 
        root->right = Insert(root->right, value); 
    
    else
    
        // Insert left node data, if the 'value' 
        // to be inserted is greater than 'root' node data. 
          
        // Process left nodes. 
        root->left = Insert(root->left, value); 
    
      
    // Return 'root' node, after insertion. 
    return root; 
  
// Inorder traversal function. 
// This gives data in sorted order. 
void BST :: Inorder(BST *root) 
    if(!root) 
    
        return
    
    Inorder(root->left); 
    print( root->data ); 
    Inorder(root->right); 
  
  
// The main function that prints 
// all unique rows in a given matrix.
void findUniqueRows(int M[ROW][COL])
{
      
    BST b, *root = NULL;
      
    //Traverse through the matrix
    for(int i=0; i<ROW; i++)
    {
        //insert the row into BST
        root=b.Insert(root,convert(M[i]));
    }
      
      
    //print 
    b.Inorder(root); 
      
}
  
// Driver Code
int main() 
    int M[ROW][COL] = {{0, 1, 0, 0, 1}, 
                       {1, 0, 1, 1, 0}, 
                       {0, 1, 0, 0, 1}, 
                       {1, 0, 1, 0, 0}}; 
  
    findUniqueRows(M); 
  
    return 0; 
chevron_right

Output: 

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

Complexity Analysis: 

Method 3: This method uses Trie data structure to solve the above problem. Trie is an efficient information retrieval data structure. Using Trie, search complexities can be brought to an optimal limit (key length). If we store keys in the binary search tree, a well-balanced BST will need time proportional to M * log N, where M is maximum string length and N is the number of keys in the tree. Using Trie, we can search the key in O(M) time. However, the penalty is on Trie storage requirements.
Note: This method will lead to Integer Overflow if the number of columns is large. 

Approach: 
Since the matrix is boolean, a variant of Trie data structure can be used where each node will be having two children one for 0 and other for 1. Insert each row in the Trie. If the row is already there, don’t print the row. If the row is not there in Trie, insert it in Trie and print it.

Algorithm: 

  1. Create a Trie where rows can be stored.
  2. Traverse through the matrix and insert the row into the Trie.
  3. Trie cannot store duplicate entries so the duplicates will be removed
  4. Traverse the Trie and print the rows.

Implementation: 

filter_none

edit
close

play_arrow

link
brightness_4
code

// Given a binary matrix of M X N of integers, 
// you need to return only unique rows of binary array 
#include <bits/stdc++.h>
using namespace std;
#define ROW 4 
#define COL 5 
  
// A Trie node 
class Node 
    public:
    bool isEndOfCol; 
    Node *child[2]; // Only two children needed for 0 and 1 
} ; 
  
  
// A utility function to allocate memory
// for a new Trie node 
Node* newNode() 
    Node* temp = new Node(); 
    temp->isEndOfCol = 0; 
    temp->child[0] = temp->child[1] = NULL; 
    return temp; 
  
// Inserts a new matrix row to Trie. 
// If row is already present, 
// then returns 0, otherwise insets the row and 
// return 1 
bool insert(Node** root, int (*M)[COL], 
                int row, int col ) 
    // base case 
    if (*root == NULL) 
        *root = newNode(); 
  
    // Recur if there are more entries in this row 
    if (col < COL) 
        return insert (&((*root)->child[M[row][col]]), 
                                        M, row, col + 1); 
  
    else // If all entries of this row are processed 
    
        // unique row found, return 1 
        if (!((*root)->isEndOfCol)) 
            return (*root)->isEndOfCol = 1; 
  
        // duplicate row found, return 0 
        return 0; 
    
  
// A utility function to print a row 
void printRow(int(*M)[COL], int row) 
    int i; 
    for(i = 0; i < COL; ++i) 
        cout << M[row][i] << " "
    cout << endl;
  
// The main function that prints 
// all unique rows in a given matrix. 
void findUniqueRows(int (*M)[COL]) 
    Node* root = NULL; // create an empty Trie 
    int i; 
  
    // Iterate through all rows 
    for (i = 0; i < ROW; ++i) 
      
        // insert row to TRIE 
        if (insert(&root, M, i, 0))
          
            // unique row found, print it 
            printRow(M, i); 
  
// Driver Code
int main() 
    int M[ROW][COL] = {{0, 1, 0, 0, 1}, 
                       {1, 0, 1, 1, 0}, 
                       {0, 1, 0, 0, 1}, 
                       {1, 0, 1, 0, 0}}; 
  
    findUniqueRows(M); 
  
    return 0; 
  
// This code is contributed by rathbhupendra
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

//Given a binary matrix of M X N of integers, you need to return only unique rows of binary array
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
  
#define ROW 4
#define COL 5
  
// A Trie node
typedef struct Node
{
    bool isEndOfCol;
    struct Node *child[2]; // Only two children needed for 0 and 1
} Node;
  
  
// A utility function to allocate memory for a new Trie node
Node* newNode()
{
    Node* temp = (Node *)malloc( sizeof( Node ) );
    temp->isEndOfCol = 0;
    temp->child[0] = temp->child[1] = NULL;
    return temp;
}
  
// Inserts a new matrix row to Trie.  If row is already
// present, then returns 0, otherwise insets the row and
// return 1
bool insert( Node** root, int (*M)[COL], int row, int col )
{
    // base case
    if ( *root == NULL )
        *root = newNode();
  
    // Recur if there are more entries in this row
    if ( col < COL )
        return insert ( &( (*root)->child[ M[row][col] ] ), M, row, col+1 );
  
    else // If all entries of this row are processed
    {
        // unique row found, return 1
        if ( !( (*root)->isEndOfCol ) )
            return (*root)->isEndOfCol = 1;
  
        // duplicate row found, return 0
        return 0;
    }
}
  
// A utility function to print a row
void printRow( int (*M)[COL], int row )
{
    int i;
    for( i = 0; i < COL; ++i )
        printf( "%d ", M[row][i] );
    printf("\n");
}
  
// The main function that prints all unique rows in a
// given matrix.
void findUniqueRows( int (*M)[COL] )
{
    Node* root = NULL; // create an empty Trie
    int i;
  
    // Iterate through all rows
    for ( i = 0; i < ROW; ++i )
        // insert row to TRIE
        if ( insert(&root, M, i, 0) )
            // unique row found, print it
            printRow( M, i );
}
  
// Driver program to test above functions
int main()
{
    int M[ROW][COL] = {{0, 1, 0, 0, 1},
        {1, 0, 1, 1, 0},
        {0, 1, 0, 0, 1},
        {1, 0, 1, 0, 0}
    };
  
    findUniqueRows( M );
  
    return 0;
}
chevron_right

Output: 

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

Complexity Analysis: 

Method 4: This method uses HashSet data structure to solve the above problem. The HashSet class implements the Set interface, backed by a hash table which is actually a HashMap instance. No guarantee is made as to the iteration order of the set which means that the class does not guarantee the constant order of elements over time. This class permits the null element. The class offers constant time performance for the basic operations like add, remove, contains and size assuming the hash function disperses the elements properly among the buckets. 

Approach: In this method convert the whole row into a single String and then if check it is already present in the HashSet or not. If the row is present then we will leave it otherwise we will print unique row and add it to HashSet.



Algorithm: 

  1. Create a HashSet where rows can be stored as a String.
  2. Traverse through the matrix and insert the row as String into the HashSet.
  3. HashSet cannot store duplicate entries so the duplicates will be removed
  4. Traverse the HashSet and print the rows.

Implementation: 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to print unique row in a 
// given binary matrix 
#include<bits/stdc++.h> 
using namespace std; 
  
void printArray(int arr[][5], int row, 
                              int col) 
    unordered_set<string> uset; 
      
    for(int i = 0; i < row; i++) 
    
        string s = ""
          
        for(int j = 0; j < col; j++) 
            s += to_string(arr[i][j]); 
          
        if(uset.count(s) == 0) 
        
            uset.insert(s); 
            cout << s << endl; 
              
        
    
  
// Driver code 
int main()
    int arr[][5] = {{0, 1, 0, 0, 1}, 
                    {1, 0, 1, 1, 0}, 
                    {0, 1, 0, 0, 1}, 
                    {1, 1, 1, 0, 0}}; 
      
    printArray(arr, 4, 5); 
  
// This code is contributed by
// rathbhupendra
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code to print unique row in a 
// given binary matrix
import java.util.HashSet;
  
public class GFG {
  
    public static void printArray(int arr[][], 
                               int row,int col)
    {
          
        HashSet<String> set = new HashSet<String>();
          
        for(int i = 0; i < row; i++)
        {
            String s = "";
              
            for(int j = 0; j < col; j++) 
                s += String.valueOf(arr[i][j]);
              
            if(!set.contains(s)) {
                set.add(s);
                System.out.println(s);
                  
            }
        }
    }
      
    // Driver code
    public static void main(String[] args) {
          
        int arr[][] = { {0, 1, 0, 0, 1},
                        {1, 0, 1, 1, 0},
                        {0, 1, 0, 0, 1},
                        {1, 1, 1, 0, 0} };
          
        printArray(arr, 4, 5);
    }
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 code to print unique row in a 
# given binary matrix
  
def printArray(matrix):
  
    rowCount = len(matrix)
    if rowCount == 0:
        return
  
    columnCount = len(matrix[0])
    if columnCount == 0:
        return
  
    row_output_format = " ".join(["%s"] * columnCount)
  
    printed = {}
  
    for row in matrix:
        routput = row_output_format % tuple(row)
        if routput not in printed:
            printed[routput] = True
            print(routput)
  
# Driver Code
mat = [[0, 1, 0, 0, 1], 
       [1, 0, 1, 1, 0], 
       [0, 1, 0, 0, 1],
       [1, 1, 1, 0, 0]]
  
printArray(mat)
  
# This code is contributed by myronwalker
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

using System;
using System.Collections.Generic;
  
// c# code to print unique row in a  
// given binary matrix 
  
public class GFG
{
  
    public static void printArray(int[][] arr, int row, int col)
    {
  
        HashSet<string> set = new HashSet<string>();
  
        for (int i = 0; i < row; i++)
        {
            string s = "";
  
            for (int j = 0; j < col; j++)
            {
                s += arr[i][j].ToString();
            }
  
            if (!set.Contains(s))
            {
                set.Add(s);
                Console.WriteLine(s);
  
            }
        }
    }
  
    // Driver code 
    public static void Main(string[] args)
    {
  
        int[][] arr = new int[][]
        {
            new int[] {0, 1, 0, 0, 1},
            new int[] {1, 0, 1, 1, 0},
            new int[] {0, 1, 0, 0, 1},
            new int[] {1, 1, 1, 0, 0}
        };
  
        printArray(arr, 4, 5);
    }
}
  
// This code is contributed by Shrikant13
chevron_right

Output: 

01001
10110
11100

Complexity Analysis: 

Thanks, Anshuman Kaushik for suggesting this method.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 

 

 

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Article Tags :
Practice Tags :