Print unique rows in a given Binary matrix
Last Updated :
23 Jul, 2025
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:
- Traverse the matrix row-wise
- For each row check if there is any similar row less than the current index.
- If any two rows are similar then do not print the row.
- Else print the row.
Implementation:
C++
// 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;
}
Java
// Given a binary matrix of M X N
// of integers, you need to return
// only unique rows of binary array
import java.io.*;
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
Python3
# 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
C#
// 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
JavaScript
<script>
// Given a binary matrix of M X N
// of integers, you need to return
// only unique rows of binary array
let ROW = 4;
let COL = 5;
// Function that prints all
// unique rows in a given matrix.
function findUniqueRows(M)
{
// Traverse through the matrix
for(let i = 0; i < ROW; i++)
{
let flag = 0;
// Check if there is similar column
// is already printed, i.e if i and
// jth column match.
for(let j = 0; j < i; j++)
{
flag = 1;
for(let 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(let j = 0; j < COL; j++)
document.write(M[i][j] + " ");
document.write("<br>");
}
}
}
// Driver Code
let 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 unknown2108
</script>
Output0 1 0 0 1
1 0 1 1 0
1 0 1 0 0
Complexity Analysis:
- Time complexity: O( ROW^2 x COL ).
So for every row check if there is any other similar row. So the time complexity is O( ROW^2 x COL ). - Auxiliary Space: O(1).
As no extra space is required.
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 left subtree of a node contains only nodes with keys lesser than the node’s key.
- The right subtree of a node contains only nodes with keys greater than the node’s key.
- The left and right subtree each must also be a binary search tree.
- There must be no duplicate nodes.
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:
- 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.
- Traverse through the matrix and insert the row into the BST.
- Traverse the BST (inorder traversal) and convert the decimal into binary array and print it.
Implementation:
C++14
// 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;
}
Java
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
import java.util.*;
class GFG{
static class BST {
int data;
BST left,right;
BST(int v){
this.data = v;
this.left = this.right = null;
}
}
final static int ROW = 4;
final static int COL = 5;
// convert array to decimal
static int convert(int arr[])
{
int sum = 0;
for(int i = 0; i < COL; i++)
{
sum += Math.pow(2,i)*arr[i];
}
return sum;
}
// print the column represented as integers
static void print(int p)
{
for(int i = 0; i < COL; i++)
{
System.out.print(p%2+" ");
p /= 2;
}
System.out.println();
}
// Insert function definition.
static BST Insert(BST root, int value)
{
if(root == null)
{
// 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.
static void Inorder(BST root)
{
if(root == null)
{
return;
}
Inorder(root.left);
print( root.data );
Inorder(root.right);
}
// The main function that prints
// all unique rows in a given matrix.
static void findUniqueRows(int M[][])
{
BST b, root = null;
// Traverse through the matrix
for(int i = 0; i < ROW; i++)
{
// insert the row into BST
root=Insert(root, convert(M[i]));
}
//print
Inorder(root);
}
// 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 Rajput-Ji
C#
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
using System;
using System.Collections.Generic;
public class GFG{
public class BST {
public int data;
public BST left,right;
public BST(int v){
this.data = v;
this.left = this.right = null;
}
}
readonly static int ROW = 4;
readonly static int COL = 5;
// convert array to decimal
static int convert(int []arr)
{
int sum = 0;
for(int i = 0; i < COL; i++)
{
sum += (int)Math.Pow(2,i)*arr[i];
}
return sum;
}
// print the column represented as integers
static void print(int p)
{
for(int i = 0; i < COL; i++)
{
Console.Write(p%2+" ");
p /= 2;
}
Console.WriteLine();
}
// Insert function definition.
static BST Insert(BST root, int value)
{
if(root == null)
{
// 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.
static void Inorder(BST root)
{
if(root == null)
{
return;
}
Inorder(root.left);
print( root.data );
Inorder(root.right);
}
public static int[] GetRow(int[,] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// The main function that prints
// all unique rows in a given matrix.
static void findUniqueRows(int [,]M)
{
BST b, root = null;
// Traverse through the matrix
for(int i = 0; i < ROW; i++)
{
// insert the row into BST
int[] row = GetRow(M,i);
root=Insert(root, convert(row));
}
//print
Inorder(root);
}
// 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 contributed by Rajput-Ji
Python3
# Given a binary matrix of M X N of integers,
# you need to return only unique rows of binary array
ROW = 4
COL = 5
# print the column represented as integers
def Print(p):
for i in range(COL):
print(p % 2 ,end = " ")
p = int(p//2)
print("")
class BST:
def __init__(self,data):
self.data = data
self.left = None
self.right = None
# Insert function definition.
def Insert(self,root, value):
if(not root):
# Insert the first node, if root is NULL.
return 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 = self.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 = self.Insert(root.left, value)
# Return 'root' node, after insertion.
return root
# Inorder traversal function.
# This gives data in sorted order.
def Inorder(self,root):
if(not root):
return
self.Inorder(root.left);
Print( root.data );
self.Inorder(root.right)
# convert array to decimal
def convert(arr):
sum=0
for i in range(COL):
sum+=pow(2,i)*arr[i]
return sum
# The main function that prints
# all unique rows in a given matrix.
def findUniqueRows(M):
b,root =BST(0),None
#Traverse through the matrix
for i in range(ROW):
#insert the row into BST
root = b.Insert(root,convert(M[i]))
#print
b.Inorder(root)
# Driver Code
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 shinjanpatra
JavaScript
<script>
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
var ROW = 4
var COL = 5
class BST
{
constructor(data)
{
this.data = data;
this.left = null;
this.right = null;
}
// Insert function definition.
Insert(root, 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 = this.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 = this.Insert(root.left, value);
}
// Return 'root' node, after insertion.
return root;
}
// Inorder traversal function.
// This gives data in sorted order.
Inorder(root)
{
if(!root)
{
return;
}
this.Inorder(root.left);
print( root.data );
this.Inorder(root.right);
}
};
// convert array to decimal
function convert(arr)
{
var sum=0;
for(var i=0; i<COL; i++)
{
sum+=Math.pow(2,i)*arr[i];
}
return sum;
}
// print the column represented as integers
function print(p)
{
for(var i=0; i<COL; i++)
{
document.write(p%2 + " ");
p=parseInt(p/2);
}
document.write("<br>");
}
// The main function that prints
// all unique rows in a given matrix.
function findUniqueRows(M)
{
var b =new BST(0),root = null;
//Traverse through the matrix
for(var i=0; i<ROW; i++)
{
//insert the row into BST
root=b.Insert(root,convert(M[i]));
}
//print
b.Inorder(root);
}
// Driver Code
var 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 rutvik_56.
</script>
Output1 0 1 0 0
1 0 1 1 0
0 1 0 0 1
Complexity Analysis:
- Time complexity: O( ROW x COL + ROW x log( ROW ) ).
To traverse the matrix time complexity is O( ROW x COL) and to insert them into BST time complexity is O(log ROW) for each row. So overall time complexity is O( ROW x COL + ROW x log( ROW ) ) - Auxiliary Space: O( ROW ).
To store the BST O(ROW) space is needed.
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:
- Create a Trie where rows can be stored.
- Traverse through the matrix and insert the row into the Trie.
- Trie cannot store duplicate entries so the duplicates will be removed
- Traverse the Trie and print the rows.
Implementation:
C++
// 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
C
//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;
}
Java
// Java code to implement the approach
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
import java.util.*;
class GFG {
static class Node {
boolean isEndOfCol;
Node[] child = new Node[2]; // Only two children
// needed for 0 and 1
}
static class Trie {
// A utility function to allocate memory for a new
// Trie node
public static Node NewNode()
{
Node temp = new Node();
temp.isEndOfCol = false;
temp.child[0] = temp.child[1] = null;
return temp;
}
// Inserts a new matrix row to Trie.
// If row is already present, then returns false,
// otherwise inserts the row and return true
public static boolean Insert(Node root, int[][] M,
int row, int col)
{
// base case
if (root == null)
root = NewNode();
// Recur if there are more entries in this row
if (col < M[0].length)
return Insert(root.child[M[row][col]], M,
row, col + 1);
else // If all entries of this row are processed
{
// unique row found, return true
if (!(root.isEndOfCol))
return root.isEndOfCol = true;
// duplicate row found, return false
return false;
}
}
// A utility function to print a row
public static void PrintRow(int[][] M, int row)
{
for (int i = 0; i < M[0].length; ++i)
System.out.print(M[row][i] + " ");
System.out.println();
}
// The main function that prints all unique rows in
// a given matrix.
public static void FindUniqueRows(int[][] M)
{
Node root = null; // create an empty Trie
// Iterate through all rows
for (int i = 0; i < M.length; ++i)
// insert row to TRIE
if (Insert(root, M, i, 0))
// unique row found, print it
PrintRow(M, i);
}
}
// 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 } };
Trie.FindUniqueRows(M);
System.out.println();
}
}
// This code is contributed by phasing17
Python3
class Node:
def __init__(self):
self.isEndOfCol = False
self.child = [None, None]
def newNode():
temp = Node()
return temp
def insert(root, M, row, col):
"""Insert a row of binary values into the trie.
If the row is already in the trie, return False.
Otherwise, return True.
"""
if root is None:
root = newNode()
if col < COL:
return insert(root.child[M[row][col]], M, row, col+1)
else:
if not root.isEndOfCol:
root.isEndOfCol = True
return True
return False
def printRow(row):
# Print a row of binary values
for i in row:
print(i, end=" ")
print()
def findUniqueRows(M):
# Find and print unique rows in a matrix of binary values
unique_rows = []
for i in range(ROW):
if not any(M[i] == row for row in unique_rows):
unique_rows.append(M[i])
for row in unique_rows:
printRow(row)
# Number of rows and columns in the matrix
ROW = 4
COL = 5
# Example matrix of binary values
M = [[0, 1, 0, 0, 1],
[1, 0, 1, 1, 0],
[0, 1, 0, 0, 1],
[1, 0, 1, 0, 0]]
# Find and print unique rows in the matrix
findUniqueRows(M)
# This code is contributed by Vikram_Shirsat
JavaScript
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
let ROW = 4
let COL = 5
// A Trie node
class Node
{
constructor()
{
this.isEndOfCol;
this.child = new Array(2); // Only two children needed for 0 and 1
}
} ;
// A utility function to allocate memory
// for a new Trie node
function newNode()
{
let temp = new Node();
temp.isEndOfCol = 0;
temp.child[0] = null;
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
function insert(root, M, row, col)
{
// base case
if (root == null)
root = newNode();
// Recur if there are more entries in this row
if (col < (M.length).length)
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))
{
(root).isEndOfCol = 1;
return 1;
}
// duplicate row found, return 0
}
return 0;
}
// A utility function to print a row
function printRow(M, row)
{
console.log(M[row].join(" "))
}
// The main function that prints
// all unique rows in a given matrix.
function findUniqueRows(M)
{
let root = null; // create an empty Trie
let 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
let 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 phasing17
C#
// Given a binary matrix of M X N of integers,
// you need to return only unique rows of binary array
using System;
namespace Trie
{
class Node
{
public bool isEndOfCol;
public Node[] child = new Node[2]; // Only two children needed for 0 and 1
}
class Trie
{
// A utility function to allocate memory
// for a new Trie node
public static Node NewNode()
{
Node temp = new Node();
temp.isEndOfCol = false;
temp.child[0] = temp.child[1] = null;
return temp;
}
// Inserts a new matrix row to Trie.
// If row is already present,
// then returns false, otherwise inserts the row and
// return true
public static bool Insert(ref Node root, int[,] M,
int row, int col )
{
// base case
if (root == null)
root = NewNode();
// Recur if there are more entries in this row
if (col < M.GetLength(1))
return Insert (ref root.child[M[row, col]], M, row, col + 1);
else // If all entries of this row are processed
{
// unique row found, return true
if (!(root.isEndOfCol))
return root.isEndOfCol = true;
// duplicate row found, return false
return false;
}
}
// A utility function to print a row
public static void PrintRow(int[,] M, int row)
{
for(int i = 0; i < M.GetLength(1); ++i)
Console.Write(M[row, i] + " ");
Console.WriteLine();
}
// The main function that prints
// all unique rows in a given matrix.
public static void FindUniqueRows(int[,] M)
{
Node root = null; // create an empty Trie
// Iterate through all rows
for (int i = 0; i < M.GetLength(0); ++i)
// insert row to TRIE
if (Insert(ref root, M, i, 0))
// unique row found, print it
PrintRow(M, i);
}
}
// Driver code
class GFG
{
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}};
Trie.FindUniqueRows(M);
Console.ReadLine();
}
}
}
Output0 1 0 0 1
1 0 1 1 0
1 0 1 0 0
Complexity Analysis:
- Time complexity: O( ROW x COL ).
To traverse the matrix and insert in the trie the time complexity is O( ROW x COL). This method has better time complexity. Also, the relative order of rows is maintained while printing but it takes a toll on space. - Auxiliary Space: O( ROW x COL ).
To store the Trie O(ROW x COL) space complexity is needed.
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:
- Create a HashSet where rows can be stored as a String.
- Traverse through the matrix and insert the row as String into the HashSet.
- HashSet cannot store duplicate entries so the duplicates will be removed
- Traverse the HashSet and print the rows.
Implementation:
C++
// 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
Java
// 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);
}
}
Python3
# 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
C#
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
JavaScript
<script>
// Javascript code to print unique row in a
// given binary matrix
function printArray(arr,row,col)
{
let set = new Set();
for(let i = 0; i < row; i++)
{
let s = "";
for(let j = 0; j < col; j++)
s += (arr[i][j]).toString();
if(!set.has(s)) {
set.add(s);
document.write(s+"<br>");
}
}
}
// Driver code
let 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);
// This code is contributed by avanitrachhadiya2155
</script>
Complexity Analysis:
- Time complexity: O( ROW x COL ).
To traverse the matrix and insert in the HashSet the time complexity is O( ROW x COL) - Auxiliary Space: O( ROW ).
To store the HashSet O(ROW x COL) space complexity is needed.
Print unique rows in a given boolean matrix
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem