Open In App

# Find same contacts in a list of contacts

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:

1. 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.
2. 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
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``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& 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 > 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 > mat,``                       ``boolean` `visited[],``                       ``ArrayList 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 sol = ``new` `ArrayList<>();` `    ``// Declare 2D adjacency matrix for mats``    ``ArrayList > 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 > 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 > 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 > mat = ``new` `List >();` `    ``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.`

Output

```0 3 2
1
4 5 ```

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 ``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 >& 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& person1,``                  ``vector& 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 > 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 > 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 parent;``    ``List size;` `    ``GFG(List> 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 person1, List 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> 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> 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> entry : contactToIndex.entrySet()) {``            ``List 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> 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> 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> 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> contacts = ``new` `List>();``        ``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();``        ``}``    ``}``}`

Output

```4 5
0 2 3
1 ```

Time Complexity: O(N * α(N)) where N is the number of contacts and α is the Inverse Ackermann Function
Space Complexity: O(N)