Find same contacts in a list of contacts
Last Updated :
23 Jul, 2025
Given a list of contacts containing the username, email and phone number in any order. Identify the same contacts (i.e., the same person having many contacts) and output the same contacts together.
Notes:
- A contact can store its three fields in any order, i.e., a phone number can appear before username or username can appear before the phone number.
- Two contacts are the same if they have either the same username or email or phone number.
Example:
Input: contact[] =
{ {"Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"},
{ "Lucky", "lucky@gmail.com", "+1234567"},
{ "gaurav123", "+5412312", "gaurav123@skype.com"}.
{ "gaurav1993", "+5412312", "gaurav@gfgQA.com"}
}
Output:
0 2 3
1
contact[2] is same as contact[3] because they both have same
contact number.
contact[0] is same as contact[3] because they both have same
e-mail address.
Therefore, contact[0] and contact[2] are also same.
We strongly recommend you to minimize your browser and try this yourself first.
Input is basically an array of structures. A structure contains three fields such that any field can represent any detail about a contact.
The idea is to first create a graph of contacts using given array. In the graph, there is an edge between vertex i to vertex j if they both have either same username or same email or same phone number. Once the graph is constructed, the task reduces to finding connected components in an undirected graph. We can find connected components either by doing DFS or BFS starting from every unvisited vertex. In below code, DFS is used.
Below is implementation of this idea.
C++
// A C++ program to find same contacts in a list of contacts
#include<bits/stdc++.h>
using namespace std;
// Structure for storing contact details.
struct contact
{
string field1, field2, field3;
};
// A utility function to fill entries in adjacency matrix
// representation of graph
void buildGraph(contact arr[], int n, int *mat[])
{
// Initialize the adjacency matrix
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
mat[i][j] = 0;
// Traverse through all contacts
for (int i = 0; i < n; i++) {
// Add mat from i to j and vice versa, if possible.
// Since length of each contact field is at max some
// constant. (say 30) so body execution of this for
// loop takes constant time.
for (int j = i+1; j < n; j++)
if (arr[i].field1 == arr[j].field1 ||
arr[i].field1 == arr[j].field2 ||
arr[i].field1 == arr[j].field3 ||
arr[i].field2 == arr[j].field1 ||
arr[i].field2 == arr[j].field2 ||
arr[i].field2 == arr[j].field3 ||
arr[i].field3 == arr[j].field1 ||
arr[i].field3 == arr[j].field2 ||
arr[i].field3 == arr[j].field3)
{
mat[i][j] = 1;
mat[j][i] = 1;
break;
}
}
}
// A recursive function to perform DFS with vertex i as source
void DFSvisit(int i, int *mat[], bool visited[], vector<int>& sol, int n)
{
visited[i] = true;
sol.push_back(i);
for (int j = 0; j < n; j++)
if (mat[i][j] && !visited[j])
DFSvisit(j, mat, visited, sol, n);
}
// Finds similar contacts in an array of contacts
void findSameContacts(contact arr[], int n)
{
// vector for storing the solution
vector<int> sol;
// Declare 2D adjacency matrix for mats
int **mat = new int*[n];
for (int i = 0; i < n; i++)
mat[i] = new int[n];
// visited array to keep track of visited nodes
bool visited[n];
memset(visited, 0, sizeof(visited));
// Fill adjacency matrix
buildGraph(arr, n, mat);
// Since, we made a graph with contacts as nodes with fields as links.
// two nodes are linked if they represent the same person.
// so, total number of connected components and nodes in each component
// will be our answer.
for (int i = 0; i < n; i++)
{
if (!visited[i])
{
DFSvisit(i, mat, visited, sol, n);
// Add delimiter to separate nodes of one component from other.
sol.push_back(-1);
}
}
// Print the solution
for (int i = 0; i < sol.size(); i++)
if (sol[i] == -1) cout << endl;
else cout << sol[i] << " ";
}
// Drive Code
int main()
{
contact arr[] = {{"Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"},
{"Lucky", "lucky@gmail.com", "+1234567"},
{"gaurav123", "+5412312", "gaurav123@skype.com"},
{"gaurav1993", "+5412312", "gaurav@gfgQA.com"},
{"raja", "+2231210", "raja@gfg.com"},
{"bahubali", "+878312", "raja"}
};
int n = sizeof arr / sizeof arr[0];
findSameContacts(arr, n);
return 0;
}
Java
// A Java program to find same contacts in a list of
// contacts
import java.util.ArrayList;
public class GFG {
// Structure for storing contact details.
static class contact {
String field1, field2, field3;
contact(String s1, String s2, String s3)
{
field1 = s1;
field2 = s2;
field3 = s3;
}
};
// A utility function to fill entries in adjacency
// matrix representation of graph
static void
buildGraph(contact arr[], int n,
ArrayList<ArrayList<Integer> > mat)
{
// Initialize the adjacency matrix
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
mat.get(i).add(0);
// Traverse through all contacts
for (int i = 0; i < n; i++) {
// Add mat from i to j and vice versa, if
// possible. Since length of each contact field
// is at max some constant. (say 30) so body
// execution of this for loop takes constant
// time.
for (int j = i + 1; j < n; j++)
if (arr[i].field1 == arr[j].field1
|| arr[i].field1 == arr[j].field2
|| arr[i].field1 == arr[j].field3
|| arr[i].field2 == arr[j].field1
|| arr[i].field2 == arr[j].field2
|| arr[i].field2 == arr[j].field3
|| arr[i].field3 == arr[j].field1
|| arr[i].field3 == arr[j].field2
|| arr[i].field3 == arr[j].field3) {
mat.get(i).set(j, 1);
mat.get(j).set(i, 1);
break;
}
}
}
// A recursive function to perform DFS with vertex i as
// source
static void DFSvisit(int i,
ArrayList<ArrayList<Integer> > mat,
boolean visited[],
ArrayList<Integer> sol, int n)
{
visited[i] = true;
sol.add(i);
for (int j = 0; j < n; j++)
if (mat.get(i).get(j) != 0 && !visited[j])
DFSvisit(j, mat, visited, sol, n);
}
// Finds similar contacts in an array of contacts
static void findSameContacts(contact arr[], int n)
{
// vector for storing the solution
ArrayList<Integer> sol = new ArrayList<>();
// Declare 2D adjacency matrix for mats
ArrayList<ArrayList<Integer> > mat
= new ArrayList<>();
for (int i = 0; i < n; i++)
mat.add(new ArrayList<>());
// visited array to keep track of visited nodes
boolean[] visited = new boolean[n];
// Fill adjacency matrix
buildGraph(arr, n, mat);
// Since, we made a graph with contacts as nodes
// with fields as links. two nodes are linked if
// they represent the same person. so, total number
// of connected components and nodes in each
// component will be our answer.
for (int i = 0; i < n; i++) {
if (!visited[i]) {
DFSvisit(i, mat, visited, sol, n);
// Add delimiter to separate nodes of one
// component from other.
sol.add(-1);
}
}
// Print the solution
for (int i = 0; i < sol.size(); i++)
if (sol.get(i) == -1)
System.out.println();
else
System.out.print(sol.get(i) + " ");
}
// Drive Code
public static void main(String[] args)
{
contact arr[] = {
new contact("Gaurav", "gaurav@gmail.com",
"gaurav@gfgQA.com"),
new contact("Lucky", "lucky@gmail.com",
"+1234567"),
new contact("gaurav123", "+5412312",
"gaurav123@skype.com"),
new contact("gaurav1993", "+5412312",
"gaurav@gfgQA.com"),
new contact("raja", "+2231210", "raja@gfg.com"),
new contact("bahubali", "+878312", "raja")
};
int n = arr.length;
findSameContacts(arr, n);
}
}
// This code is contributed by Karandeep1234
Python3
# A Python3 program to find same contacts
# in a list of contacts
# Structure for storing contact details.
class contact:
def __init__(self, field1,
field2, field3):
self.field1 = field1
self.field2 = field2
self.field3 = field3
# A utility function to fill entries in
# adjacency matrix representation of graph
def buildGraph(arr, n, mat):
# Initialize the adjacency matrix
for i in range(n):
for j in range(n):
mat[i][j] = 0
# Traverse through all contacts
for i in range(n):
# Add mat from i to j and vice versa,
# if possible. Since length of each
# contact field is at max some constant.
# (say 30) so body execution of this for
# loop takes constant time.
for j in range(i + 1, n):
if (arr[i].field1 == arr[j].field1 or
arr[i].field1 == arr[j].field2 or
arr[i].field1 == arr[j].field3 or
arr[i].field2 == arr[j].field1 or
arr[i].field2 == arr[j].field2 or
arr[i].field2 == arr[j].field3 or
arr[i].field3 == arr[j].field1 or
arr[i].field3 == arr[j].field2 or
arr[i].field3 == arr[j].field3):
mat[i][j] = 1
mat[j][i] = 1
break
# A recursive function to perform DFS
# with vertex i as source
def DFSvisit(i, mat, visited, sol, n):
visited[i] = True
sol.append(i)
for j in range(n):
if (mat[i][j] and not visited[j]):
DFSvisit(j, mat, visited, sol, n)
# Finds similar contacts in an
# array of contacts
def findSameContacts(arr, n):
# vector for storing the solution
sol = []
# Declare 2D adjacency matrix for mats
mat = [[None] * n for i in range(n)]
# visited array to keep track
# of visited nodes
visited = [0] * n
# Fill adjacency matrix
buildGraph(arr, n, mat)
# Since, we made a graph with contacts
# as nodes with fields as links. Two
# nodes are linked if they represent
# the same person. So, total number of
# connected components and nodes in each
# component will be our answer.
for i in range(n):
if (not visited[i]):
DFSvisit(i, mat, visited, sol, n)
# Add delimiter to separate nodes
# of one component from other.
sol.append(-1)
# Print the solution
for i in range(len(sol)):
if (sol[i] == -1):
print()
else:
print(sol[i], end = " ")
# Driver Code
if __name__ == '__main__':
arr = [contact("Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"),
contact("Lucky", "lucky@gmail.com", "+1234567"),
contact("gaurav123", "+5412312", "gaurav123@skype.com"),
contact("gaurav1993", "+5412312", "gaurav@gfgQA.com"),
contact("raja", "+2231210", "raja@gfg.com"),
contact("bahubali", "+878312", "raja")]
n = len(arr)
findSameContacts(arr, n)
# This code is contributed by PranchalK
C#
// A C# program to find same contacts in a list of
// contacts
using System;
using System.Collections;
using System.Collections.Generic;
public class GFG {
// Structure for storing contact details.
public class contact {
public string field1, field2, field3;
public contact(string s1, string s2, string s3)
{
field1 = s1;
field2 = s2;
field3 = s3;
}
};
// A utility function to fill entries in adjacency
// matrix representation of graph
static void buildGraph(contact[] arr, int n,
List<List<int> > mat)
{
// Initialize the adjacency matrix
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
mat[i].Add(0);
// Traverse through all contacts
for (int i = 0; i < n; i++) {
// Add mat from i to j and vice versa, if
// possible. Since length of each contact field
// is at max some constant. (say 30) so body
// execution of this for loop takes constant
// time.
for (int j = i + 1; j < n; j++)
if (arr[i].field1 == arr[j].field1
|| arr[i].field1 == arr[j].field2
|| arr[i].field1 == arr[j].field3
|| arr[i].field2 == arr[j].field1
|| arr[i].field2 == arr[j].field2
|| arr[i].field2 == arr[j].field3
|| arr[i].field3 == arr[j].field1
|| arr[i].field3 == arr[j].field2
|| arr[i].field3 == arr[j].field3) {
mat[i][j] = 1;
mat[j][i] = 1;
break;
}
}
}
// A recursive function to perform DFS with vertex i as
// source
static void DFSvisit(int i, List<List<int> > mat,
bool[] visited, List<int> sol,
int n)
{
visited[i] = true;
sol.Add(i);
for (int j = 0; j < n; j++)
if (mat[i][j] != 0 && !visited[j])
DFSvisit(j, mat, visited, sol, n);
}
// Finds similar contacts in an array of contacts
static void findSameContacts(contact[] arr, int n)
{
// vector for storing the solution
List<int> sol = new List<int>();
// Declare 2D adjacency matrix for mats
List<List<int> > mat = new List<List<int> >();
for (int i = 0; i < n; i++)
mat.Add(new List<int>());
// visited array to keep track of visited nodes
bool[] visited = new bool[n];
// Fill adjacency matrix
buildGraph(arr, n, mat);
// Since, we made a graph with contacts as nodes
// with fields as links. two nodes are linked if
// they represent the same person. so, total number
// of connected components and nodes in each
// component will be our answer.
for (int i = 0; i < n; i++) {
if (!visited[i]) {
DFSvisit(i, mat, visited, sol, n);
// Add delimiter to separate nodes of one
// component from other.
sol.Add(-1);
}
}
// Print the solution
for (int i = 0; i < sol.Count; i++)
if (sol[i] == -1)
Console.WriteLine();
else
Console.Write(sol[i] + " ");
}
// Drive Code
public static void Main(string[] args)
{
contact[] arr = {
new contact("Gaurav", "gaurav@gmail.com",
"gaurav@gfgQA.com"),
new contact("Lucky", "lucky@gmail.com",
"+1234567"),
new contact("gaurav123", "+5412312",
"gaurav123@skype.com"),
new contact("gaurav1993", "+5412312",
"gaurav@gfgQA.com"),
new contact("raja", "+2231210", "raja@gfg.com"),
new contact("bahubali", "+878312", "raja")
};
int n = arr.Length;
findSameContacts(arr, n);
}
}
// This code is contributed by Karandeep1234
JavaScript
// JS code for the above approach
// Structure for storing contact details.
class Contact {
constructor(field1, field2, field3) {
this.field1 = field1;
this.field2 = field2;
this.field3 = field3;
}
}
// A utility function to fill entries in
// adjacency matrix representation of graph
function buildGraph(arr, n, mat) {
// Initialize the adjacency matrix
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
mat[i][j] = 0;
}
}
// Traverse through all contacts
for (let i = 0; i < n; i++) {
// Add mat from i to j and vice versa,
// if possible. Since length of each
// contact field is at max some constant.
// (say 30) so body execution of this for
// loop takes constant time.
for (let j = i + 1; j < n; j++) {
if (arr[i].field1 === arr[j].field1 ||
arr[i].field1 === arr[j].field2 ||
arr[i].field1 === arr[j].field3 ||
arr[i].field2 === arr[j].field1 ||
arr[i].field2 === arr[j].field2 ||
arr[i].field2 === arr[j].field3 ||
arr[i].field3 === arr[j].field1 ||
arr[i].field3 === arr[j].field2 ||
arr[i].field3 === arr[j].field3) {
mat[i][j] = 1;
mat[j][i] = 1;
break;
}
}
}
}
// A recursive function to perform DFS
// with vertex i as source
function DFSvisit(i, mat, visited, sol, n) {
visited[i] = true;
sol.push(i);
for (let j = 0; j < n; j++) {
if (mat[i][j] && !visited[j]) {
DFSvisit(j, mat, visited, sol, n);
}
}
}
// Finds similar contacts in an
// array of contacts
function findSameContacts(arr, n) {
// vector for storing the solution
let sol = [];
// Declare 2D adjacency matrix for mats
let mat = new Array(n).fill().map(() => new Array(n));
// visited array to keep track
// of visited nodes
let visited = new Array(n).fill(0);
// Fill adjacency matrix
buildGraph(arr, n, mat);
// Since, we made a graph with contacts
// as nodes with fields as links. Two
// nodes are linked if they represent
// the same person. So, total number of
// connected components and nodes in each
// component will be our answer.
for (let i = 0; i < n; i++) {
if (!visited[i]) {
DFSvisit(i, mat, visited, sol, n);
// Add delimiter to separate nodes
// of one component from other.
sol.push(-1);
}
}
// Print the solution
for (let i = 0; i < sol.length; i++) {
if (sol[i] === -1) {
console.log("");
} else {
process.stdout.write(sol[i] + " ");
}
}
}
// Driver code
let arr = [new Contact("Gaurav",
"gaurav@gmail.com", "gaurav@gfgQA.com"),
new Contact("Lucky", "lucky@gmail.com", "+1234567"),
new Contact("gaurav123", "+5412312", "gaurav123@skype.com"),
new Contact("gaurav1993", "+5412312", "gaurav@gfgQA.com"),
new Contact("raja", "+2231210", "raja@gfg.com"),
new Contact("bahubali", "+878312", "raja") ];
let n = arr.length;
findSameContacts(arr, n);
// This code is contributed by lokeshpotta20.
Time complexity: O(n2) where n is number of contacts.
Auxiliary Space : O(N)
Another Approach: (Using Union Find)
The problem can be solved with Union Find as well. Here, we unify all the people who have at least one common contact. We need to isolate all the indices which have common contacts. To achieve this, we can maintain an array of the map of indices for each contact and unify all the indices corresponding to them. After the Union Find, we get Disjoint Sets which are distinct people.
C++14
// CPP14 program to find common contacts.
#include <bits/stdc++.h>
using namespace std;
// The class DSU will implement the Union Find
class DSU {
vector<int> parent, size;
public:
// In the constructor, we assign the each index as its
// own parent and size as the number of contacts
// available for that index
DSU(vector<vector<string> >& contacts)
{
for (int i = 0; i < contacts.size(); i++) {
parent.push_back(i);
size.push_back(contacts[i].size());
}
}
// Finds the set in which the element belongs. Path
// compression is used to optimise time complexity
int findSet(int v)
{
if (v == parent[v])
return v;
return parent[v] = findSet(parent[v]);
}
// Unifies the sets a and b where, the element belonging
// to the smaller set is merged to the one belonging to
// the smaller set
void unionSet(int a, int b, vector<string>& person1,
vector<string>& person2)
{
if (size[a] > size[b]) {
parent[b] = a;
size[a] += size[b];
for (auto contact : person2)
person1.push_back(contact);
}
else {
parent[a] = b;
size[b] += size[a];
for (auto contact : person1)
person2.push_back(contact);
}
}
};
// Driver Code
int main()
{
vector<vector<string> > contacts = {
{ "Gaurav", "gaurav@gmail.com",
"gaurav@gfgQA.com" },
{ "Lucky", "lucky@gmail.com", "+1234567" },
{ "gaurav123", "+5412312", "gaurav123@skype.com" },
{ "gaurav1993", "+5412312", "gaurav@gfgQA.com" },
{ "raja", "+2231210", "raja@gfg.com" },
{ "bahubali", "+878312", "raja" }
};
// Initializing the object of DSU class
DSU dsu(contacts);
// Will contain the mapping of a contact to all the
// indices it is present within
unordered_map<string, vector<int> > contactToIndex;
for (int index = 0; index < contacts.size(); index++) {
for (auto contact : contacts[index])
contactToIndex[contact].push_back(index);
}
// Unifies the sets of each contact if they are not
// present in the same set
for (auto contact : contactToIndex) {
vector<int> indices = contact.second;
for (int i = 0; i < indices.size() - 1; i++) {
int set1 = dsu.findSet(indices[i]),
set2 = dsu.findSet(indices[i + 1]);
if (set1 != set2)
dsu.unionSet(set1, set2, contacts[set1],
contacts[set2]);
}
}
// Contains a map of all the distinct sets available
// after union find has been completed
unordered_map<int, vector<int> > unifiedSet;
// All parents are mapped to the elements in the set
for (int i = 0; i < contacts.size(); i++) {
unifiedSet[dsu.findSet(i)].push_back(i);
}
// Printing out elements from distinct sets
for (auto eachSet : unifiedSet) {
for (auto element : eachSet.second)
cout << element << " ";
cout << endl;
}
return 0;
}
Python3
class DSU:
def __init__(self, contacts):
# In the constructor, we assign each index
# as its own parent and size as the number
#of contacts available for that index
self.parent = [i for i in range(len(contacts))]
self.size = [len(contacts[i]) for i in range(len(contacts))]
# Finds the set in which the element belongs.
# Path compression is used to optimize time complexity.
def findSet(self, v):
if v == self.parent[v]:
return v
self.parent[v] = self.findSet(self.parent[v])
return self.parent[v]
# Unifies the sets a and b where, the element
# belonging to the smaller set is merged to
# the one belonging to the smaller set
def unionSet(self, a, b, person1, person2):
if self.size[a] > self.size[b]:
self.parent[b] = a
self.size[a] += self.size[b]
for contact in person2:
person1.append(contact)
else:
self.parent[a] = b
self.size[b] += self.size[a]
for contact in person1:
person2.append(contact)
# Driver Code
if __name__ == '__main__':
contacts = [
["Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"],
["Lucky", "lucky@gmail.com", "+1234567"],
["gaurav123", "+5412312", "gaurav123@skype.com"],
["gaurav1993", "+5412312", "gaurav@gfgQA.com"],
["raja", "+2231210", "raja@gfg.com"],
["bahubali", "+878312", "raja"]
]
# Initializing the object of DSU class
dsu = DSU(contacts)
# Will contain the mapping of a contact to all the indices it is present within
contactToIndex = {}
for index in range(len(contacts)):
for contact in contacts[index]:
if contact not in contactToIndex:
contactToIndex[contact] = []
contactToIndex[contact].append(index)
# Unifies the sets of each contact if they are not present in the same set
for contact, indices in contactToIndex.items():
for i in range(len(indices) - 1):
set1 = dsu.findSet(indices[i])
set2 = dsu.findSet(indices[i + 1])
if set1 != set2:
dsu.unionSet(set1, set2, contacts[set1], contacts[set2])
# Contains a map of all the distinct sets
# available after union find has been completed
unifiedSet = {}
# All parents are mapped to the elements in the set
for i in range(len(contacts)):
if dsu.parent[i] not in unifiedSet:
unifiedSet[dsu.parent[i]] = []
unifiedSet[dsu.parent[i]].append(i)
# Printing out elements from distinct sets
for eachSet in unifiedSet.values():
for element in eachSet:
print(element, end=" ")
print()
JavaScript
class DSU {
constructor(contacts) {
// In the constructor, we assign each index
// as its own parent and size as the number
//of contacts available for that index
this.parent = [...Array(contacts.length).keys()];
this.size = contacts.map(contact => contact.length);
}
// Finds the set in which the element belongs.
// Path compression is used to optimize time complexity.
findSet(v) {
if (v === this.parent[v]) {
return v;
}
this.parent[v] = this.findSet(this.parent[v]);
return this.parent[v];
}
// Unifies the sets a and b where, the element
// belonging to the smaller set is merged to
// the one belonging to the smaller set
unionSet(a, b, person1, person2) {
if (this.size[a] > this.size[b]) {
this.parent[b] = a;
this.size[a] += this.size[b];
person2.forEach(contact => {
person1.push(contact);
});
} else {
this.parent[a] = b;
this.size[b] += this.size[a];
person1.forEach(contact => {
person2.push(contact);
});
}
}
}
const contacts = [
["Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"],
["Lucky", "lucky@gmail.com", "+1234567"],
["gaurav123", "+5412312", "gaurav123@skype.com"],
["gaurav1993", "+5412312", "gaurav@gfgQA.com"],
["raja", "+2231210", "raja@gfg.com"],
["bahubali", "+878312", "raja"]
];
// Initializing the object of DSU class
const dsu = new DSU(contacts);
// Will contain the mapping of a contact to all the indices it is present within
const contactToIndex = {};
for (let index = 0; index < contacts.length; index++) {
const contactList = contacts[index];
for (let i = 0; i < contactList.length; i++) {
const contact = contactList[i];
if (!contactToIndex[contact]) {
contactToIndex[contact] = [];
}
contactToIndex[contact].push(index);
}
}
// Unifies the sets of each contact if they are not present in the same set
for (const [contact, indices] of Object.entries(contactToIndex)) {
for (let i = 0; i < indices.length - 1; i++) {
const set1 = dsu.findSet(indices[i]);
const set2 = dsu.findSet(indices[i + 1]);
if (set1 !== set2) {
dsu.unionSet(set1, set2, contacts[set1], contacts[set2]);
}
}
}
// Contains a map of all the distinct sets
// available after union find has been completed
const unifiedSet = [];
// All parents are mapped to the elements in the set
for (let i = 0; i < contacts.length; i++) {
const parent = dsu.parent[i];
if (!unifiedSet[parent]) {
unifiedSet[parent] = [];
}
unifiedSet[parent].push(i);
}
for (const eachSet of Object.values(unifiedSet)) {
if (eachSet) { // add a check here to ensure eachSet exists
const elements = Array.from(eachSet);
for (const element of elements) {
process.stdout.write(`${element} `);
}
process.stdout.write("\n");
}
}
Java
import java.util.*;
class GFG {
List<Integer> parent;
List<Integer> size;
GFG(List<List<String>> contacts) {
parent = new ArrayList<>();
size = new ArrayList<>();
for (int i = 0; i < contacts.size(); i++) {
parent.add(i);
size.add(contacts.get(i).size());
}
}
int findSet(int v) {
if (v == parent.get(v))
return v;
return parent.set(v, findSet(parent.get(v)));
}
void unionSet(int a, int b, List<String> person1, List<String> person2) {
if (size.get(a) > size.get(b)) {
parent.set(b, a);
size.set(a, size.get(a) + size.get(b));
person1.addAll(person2);
}
else {
parent.set(a, b);
size.set(b, size.get(b) + size.get(a));
person2.addAll(person1);
}
}
}
public class Main {
public static void main(String[] args) {
List<List<String>> contacts = new ArrayList<>();
contacts.add(Arrays.asList("Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com"));
contacts.add(Arrays.asList("Lucky", "lucky@gmail.com", "+1234567"));
contacts.add(Arrays.asList("gaurav123", "+5412312", "gaurav123@skype.com"));
contacts.add(Arrays.asList("gaurav1993", "+5412312", "gaurav@gfgQA.com"));
contacts.add(Arrays.asList("raja", "+2231210", "raja@gfg.com"));
contacts.add(Arrays.asList("bahubali", "+878312", "raja"));
GFG GFG = new GFG(contacts);
Map<String, List<Integer>> contactToIndex = new HashMap<>();
for (int index = 0; index < contacts.size(); index++) {
for (String contact : contacts.get(index)) {
if (!contactToIndex.containsKey(contact)) {
contactToIndex.put(contact, new ArrayList<>());
}
contactToIndex.get(contact).add(index);
}
}
for (Map.Entry<String, List<Integer>> entry : contactToIndex.entrySet()) {
List<Integer> indices = entry.getValue();
for (int i = 0; i < indices.size() - 1; i++) {
int set1 = GFG.findSet(indices.get(i));
int set2 = GFG.findSet(indices.get(i + 1));
if (set1 != set2) {
GFG.unionSet(set1, set2, contacts.get(set1), contacts.get(set2));
}
}
}
Map<Integer, List<Integer>> unifiedSet = new HashMap<>();
for (int i = 0; i < contacts.size(); i++) {
int parent = GFG.findSet(i);
if (!unifiedSet.containsKey(parent)) {
unifiedSet.put(parent, new ArrayList<>());
}
unifiedSet.get(parent).add(i);
}
for (Map.Entry<Integer, List<Integer>> entry : unifiedSet.entrySet()) {
for (int element : entry.getValue()) {
System.out.print(element + " ");
}
System.out.println();
}
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG
{
private List<int> parent;
private List<int> size;
public GFG(List<List<string>> contacts)
{
parent = new List<int>();
size = new List<int>();
for (int i = 0; i < contacts.Count; i++)
{
parent.Add(i);
size.Add(contacts[i].Count);
}
}
public int FindSet(int v)
{
if (v == parent[v])
return v;
return parent[v] = FindSet(parent[v]);
}
public void UnionSet(int a, int b, List<string> person1, List<string> person2)
{
if (size[a] > size[b])
{
parent[b] = a;
size[a] += size[b];
person1.AddRange(person2);
}
else
{
parent[a] = b;
size[b] += size[a];
person2.AddRange(person1);
}
}
}
public class Program
{
public static void Main()
{
List<List<string>> contacts = new List<List<string>>();
contacts.Add(new List<string> { "Gaurav", "gaurav@gmail.com", "gaurav@gfgQA.com" });
contacts.Add(new List<string> { "Lucky", "lucky@gmail.com", "+1234567" });
contacts.Add(new List<string> { "gaurav123", "+5412312", "gaurav123@skype.com" });
contacts.Add(new List<string> { "gaurav1993", "+5412312", "gaurav@gfgQA.com" });
contacts.Add(new List<string> { "raja", "+2231210", "raja@gfg.com" });
contacts.Add(new List<string> { "bahubali", "+878312", "raja" });
GFG gfg = new GFG(contacts);
Dictionary<string, List<int>> contactToIndex = new Dictionary<string, List<int>>();
for (int index = 0; index < contacts.Count; index++)
{
foreach (string contact in contacts[index])
{
if (!contactToIndex.ContainsKey(contact))
{
contactToIndex.Add(contact, new List<int>());
}
contactToIndex[contact].Add(index);
}
}
foreach (KeyValuePair<string, List<int>> entry in contactToIndex)
{
List<int> indices = entry.Value;
for (int i = 0; i < indices.Count - 1; i++)
{
int set1 = gfg.FindSet(indices[i]);
int set2 = gfg.FindSet(indices[i + 1]);
if (set1 != set2)
{
gfg.UnionSet(set1, set2, contacts[set1], contacts[set2]);
}
}
}
Dictionary<int, List<int>> unifiedSet = new Dictionary<int, List<int>>();
for (int i = 0; i < contacts.Count; i++)
{
int parent = gfg.FindSet(i);
if (!unifiedSet.ContainsKey(parent))
{
unifiedSet.Add(parent, new List<int>());
}
unifiedSet[parent].Add(i);
}
foreach (KeyValuePair<int, List<int>> entry in unifiedSet)
{
foreach (int element in entry.Value)
{
Console.Write(element + " ");
}
Console.WriteLine();
}
}
}
Time Complexity: O(N * α(N)) where N is the number of contacts and α is the Inverse Ackermann Function
Space Complexity: O(N)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem