Count of Disjoint Groups by grouping points that are at most K distance apart

• Difficulty Level : Medium
• Last Updated : 23 Nov, 2022

Given a 2D array arr[] and value K, where each list in arr[] represents a point on Cartesian coordinates, the task is to group the given points if the distance between them is less than or equal to K and find the total number of disjoint groups.

Note: If points ‘a’ and ‘b’ are in the same group and ‘a’, ‘d’ are in the same group then ‘b’ and ‘d’ are also in the same group.

Examples:

Input: arr[] = {{73, -62}, {2, 2}, {3, 3}}, K = 1
Output: 3
Explanation: There are no two points which have distance = 1.
So all three points form different disjoint sets.

Input: arr[] = {{3, 6}, {4, 2}, {3, 3}, {4, 9}}, K = 2
Output: 3
Explanation: The points{4, 2} and {3, 3} form a group.

An approach using Disjoint set union:

The idea to solve this problem is based on the concept of disjoint set union

Assume all points as a disjoint group. So, number of disjoint groups initially will be N (N is the number of points in the given array). Generate all the possible pairs of points in the given array arr[], then check if the distance between them is less than or equals to K or not. If condition is satisfied, then merge them together and reduce the count of number of disjoint sets by 1.

Follow the steps below to implement the above idea:

• Create a parent and rank array of size N, where N is the number of points in the given array and a variable (say cc) to store the number of the connected components and initialize cc by N.
• Initialize the parent array for ith point to i (i.e parent[i] = i) and rank[i] = 1.
• Generate all the possible pairs of points in the given array arr
• Calculate the distance between the point and check if the distance between them is less than or equal to K or not
• if the distance is less the equal to k,
• Call the union1 function to merge these points.
• If merge is done successfully then reduce the count of cc by 1.
• Finally, return the count of cc.

Below is the implementation of the above approach:

C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// Function to find the parent of a node` `int` `find(``int` `x, vector<``int``>& parent)` `{` `    ``if` `(x == parent[x])` `        ``return` `x;`   `    ``return` `parent[x] = find(parent[x], parent);` `}`   `// Function to unite two sets` `bool` `union1(``int` `x, ``int` `y, vector<``int``>& parent,` `            ``vector<``int``>& rank)` `{` `    ``int` `lx = find(x, parent);` `    ``int` `ly = find(y, parent);`   `    ``// Condition of merging` `    ``if` `(lx != ly) {` `        ``if` `(rank[lx] > rank[ly]) {` `            ``parent[ly] = lx;` `        ``}` `        ``else` `if` `(rank[lx] < rank[ly]) {` `            ``parent[lx] = ly;` `        ``}` `        ``else` `{` `            ``parent[lx] = ly;` `            ``rank[ly] += 1;` `        ``}`   `        ``// Return true for merging two` `        ``// groups into one groups` `        ``return` `true``;` `    ``}`   `    ``// Return false if points are` `    ``// already merged.` `    ``return` `false``;` `}`   `// Function to count the number of groups` `// formed after grouping the points` `int` `solve(vector >& points, ``int` `k)` `{` `    ``int` `n = points.size(),`   `        ``// cc is for number of` `        ``// connected component` `        ``cc = n;`   `    ``vector<``int``> parent(n), rank(n);`   `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``parent[i] = i;` `        ``rank[i] = 1;` `    ``}`   `    ``// Iterate over all pairs of point` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = i + 1; j < n; j++) {`   `            ``double` `x1 = points[i][0], y1 = points[i][1];` `            ``double` `x2 = points[j][0], y2 = points[j][1];`   `            ``// Calculate the distance` `            ``// between the points` `            ``double` `dist = (``double``)``sqrt``(``pow``(x2 - x1, 2)` `                                       ``+ ``pow``(y2 - y1, 2));`   `            ``// Check the given condition` `            ``if` `(dist <= k) {`   `                ``// Merge this pair of points` `                ``// into one group` `                ``bool` `merge = union1(i, j, parent, rank);`   `                ``// If these points are getting` `                ``// merged then reduce the cc by 1;` `                ``if` `(merge)` `                    ``cc--;` `            ``}` `        ``}` `    ``}`   `    ``return` `cc;` `}`   `// Driver code` `int` `main()` `{` `    ``vector > arr` `        ``= { { 73, -62 }, { 2, 2 }, { 3, 3 } };` `    ``int` `K = 1;` `    ``int` `result = solve(arr, K);`   `    ``// Function Call` `    ``cout << result << endl;` `    ``return` `0;` `}`

Java

 `// Java code to implement the approach` `import` `java.io.*;`   `class` `GFG ` `{` `  `  `  ``// Function to find the parent of a node` `  ``public` `static` `int` `find(``int` `x, ``int` `parent[])` `  ``{` `    ``if` `(x == parent[x])` `      ``return` `x;`   `    ``return` `parent[x] = find(parent[x], parent);` `  ``}`   `  ``// Function to unite two sets` `  ``public` `static` `boolean` `union1(``int` `x, ``int` `y, ``int` `parent[],` `                               ``int` `rank[])` `  ``{` `    ``int` `lx = find(x, parent);` `    ``int` `ly = find(y, parent);`   `    ``// Condition of merging` `    ``if` `(lx != ly) {` `      ``if` `(rank[lx] > rank[ly]) {` `        ``parent[ly] = lx;` `      ``}` `      ``else` `if` `(rank[lx] < rank[ly]) {` `        ``parent[lx] = ly;` `      ``}` `      ``else` `{` `        ``parent[lx] = ly;` `        ``rank[ly] += ``1``;` `      ``}`   `      ``// Return true for merging two` `      ``// groups into one groups` `      ``return` `true``;` `    ``}`   `    ``// Return false if points are` `    ``// already merged.` `    ``return` `false``;` `  ``}`   `  ``// Function to count the number of groups` `  ``// formed after grouping the points` `  ``public` `static` `int` `solve(``int` `points[][], ``int` `k)` `  ``{` `    ``int` `n = points.length,`   `    ``// cc is for number of` `    ``// connected component` `    ``cc = n;`   `    ``int` `parent[] = ``new` `int``[n];` `    ``int` `rank[] = ``new` `int``[n];`   `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``parent[i] = i;` `      ``rank[i] = ``1``;` `    ``}`   `    ``// Iterate over all pairs of point` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``for` `(``int` `j = i + ``1``; j < n; j++) {`   `        ``double` `x1 = points[i][``0``], y1 = points[i][``1``];` `        ``double` `x2 = points[j][``0``], y2 = points[j][``1``];`   `        ``// Calculate the distance` `        ``// between the points` `        ``double` `dist = (``double``)Math.sqrt(` `          ``Math.pow(x2 - x1, ``2``)` `          ``+ Math.pow(y2 - y1, ``2``));`   `        ``// Check the given condition` `        ``if` `(dist <= k) {`   `          ``// Merge this pair of points` `          ``// into one group` `          ``boolean` `merge` `            ``= union1(i, j, parent, rank);`   `          ``// If these points are getting` `          ``// merged then reduce the cc by 1;` `          ``if` `(merge == ``true``)` `            ``cc--;` `        ``}` `      ``}` `    ``}`   `    ``return` `cc;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``int` `arr[][] = { { ``73``, -``62` `}, { ``2``, ``2` `}, { ``3``, ``3` `} };` `    ``int` `K = ``1``;` `    ``int` `result = solve(arr, K);`   `    ``// Function Call` `    ``System.out.println(result);` `  ``}` `}`   `// This code is contributed by Rohit Pradhan`

Python3

 `import` `math`   `class` `GFG :` `  `  `    ``# Function to find the parent of a node` `    ``@staticmethod` `    ``def`  `find( x,  parent) :` `        ``if` `(x ``=``=` `parent[x]) :` `            ``return` `x` `        ``return` `        ``parent[x] ``=` `GFG.find(parent[x], parent)` `        `  `    ``# Function to unite two sets` `    ``@staticmethod` `    ``def`  `union1( x,  y,  parent,  rank) :` `        ``lx ``=` `GFG.find(x, parent)` `        ``ly ``=` `GFG.find(y, parent)` `        `  `        ``# Condition of merging` `        ``if` `(lx !``=` `ly) :` `            ``if` `(rank[lx] > rank[ly]) :` `                ``parent[ly] ``=` `lx` `            ``elif``(rank[lx] < rank[ly]) :` `                ``parent[lx] ``=` `ly` `            ``else` `:` `                ``parent[lx] ``=` `ly` `                ``rank[ly] ``+``=` `1` `                `  `            ``# Return true for merging two` `            ``# groups into one groups` `            ``return` `True` `          `  `        ``# Return false if points are` `        ``# already merged.` `        ``return` `False` `      `  `    ``# Function to count the number of groups` `    ``# formed after grouping the points` `    ``@staticmethod` `    ``def`  `solve( points,  k) :` `        ``n ``=` `len``(points)` `        ``cc ``=` `n` `        ``parent ``=` `[``0``] ``*` `(n)` `        ``rank ``=` `[``0``] ``*` `(n)` `        ``i ``=` `0` `        ``while` `(i < n) :` `            ``parent[i] ``=` `i` `            ``rank[i] ``=` `1` `            ``i ``+``=` `1` `            `  `        ``# Iterate over all pairs of point` `        ``i ``=` `0` `        ``while` `(i < n) :` `            ``j ``=` `i ``+` `1` `            ``while` `(j < n) :` `                ``x1 ``=` `points[i][``0``]` `                ``y1 ``=` `points[i][``1``]` `                ``x2 ``=` `points[j][``0``]` `                ``y2 ``=` `points[j][``1``]` `                `  `                ``# Calculate the distance` `                ``# between the points` `                ``dist ``=` `float``(math.sqrt(math.``pow``(x2 ``-` `x1,``2``) ``+` `math.``pow``(y2 ``-` `y1,``2``)))` `                `  `                ``# Check the given condition` `                ``if` `(dist <``=` `k) :` `                  `  `                    ``# Merge this pair of points` `                    ``# into one group` `                    ``merge ``=` `GFG.union1(i, j, parent, rank)` `                    `  `                    ``# If these points are getting` `                    ``# merged then reduce the cc by 1;` `                    ``if` `(merge ``=``=` `True``) :` `                        ``cc ``-``=` `1` `                ``j ``+``=` `1` `            ``i ``+``=` `1` `        ``return` `cc` `      `  `    ``# Driver Code` `    ``@staticmethod` `    ``def` `main( args) :` `        ``arr ``=` `[[``73``, ``-``62``], [``2``, ``2``], [``3``, ``3``]]` `        ``K ``=` `1` `        ``result ``=` `GFG.solve(arr, K)` `        `  `        ``# Function Call` `        ``print``(result)` `    `  `if` `__name__``=``=``"__main__"``:` `    ``GFG.main([])` `    `  `    ``# This code is contributed by aadityaburujwale.`

C#

 `// C# code to implement the approach` `using` `System;` `class` `GFG ` `{` `  `  `    ``// Function to find the parent of a node` `    ``static` `int` `find(``int` `x, ``int``[] parent)` `    ``{` `        ``if` `(x == parent[x])` `            ``return` `x;`   `        ``return` `parent[x] = find(parent[x], parent);` `    ``}`   `    ``// Function to unite two sets` `    ``static` `bool` `union1(``int` `x, ``int` `y, ``int``[] parent,` `                       ``int``[] rank)` `    ``{` `        ``int` `lx = find(x, parent);` `        ``int` `ly = find(y, parent);`   `        ``// Condition of merging` `        ``if` `(lx != ly) {` `            ``if` `(rank[lx] > rank[ly]) {` `                ``parent[ly] = lx;` `            ``}` `            ``else` `if` `(rank[lx] < rank[ly]) {` `                ``parent[lx] = ly;` `            ``}` `            ``else` `{` `                ``parent[lx] = ly;` `                ``rank[ly] += 1;` `            ``}`   `            ``// Return true for merging two` `            ``// groups into one groups` `            ``return` `true``;` `        ``}`   `        ``// Return false if points are` `        ``// already merged.` `        ``return` `false``;` `    ``}`   `    ``// Function to count the number of groups` `    ``// formed after grouping the points` `    ``static` `int` `solve(``int``[, ] points, ``int` `k, ``int` `n, ``int` `m)` `    ``{`   `        ``// cc is for number of` `        ``// connected component` `        ``int` `cc = n;` `        ``int``[] parent = ``new` `int``[n];` `        ``int``[] rank = ``new` `int``[n];` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``parent[i] = i;` `            ``rank[i] = 1;` `        ``}`   `        ``// Iterate over all pairs of point` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``for` `(``int` `j = i + 1; j < n; j++) {`   `                ``double` `x1 = (``double``)points[i, 0],` `                       ``y1 = (``double``)points[i, 1];` `                ``double` `x2 = (``double``)points[j, 0],` `                       ``y2 = (``double``)points[j, 1];`   `                ``// Calculate the distance` `                ``// between the points` `                ``double` `dist = (``double``)Math.Sqrt(` `                    ``Math.Pow(x2 - x1, 2)` `                    ``+ Math.Pow(y2 - y1, 2));`   `                ``// Check the given condition` `                ``if` `(dist <= k) {`   `                    ``// Merge this pair of points` `                    ``// into one group` `                    ``bool` `merge = union1(i, j, parent, rank);`   `                    ``// If these points are getting` `                    ``// merged then reduce the cc by 1;` `                    ``if` `(merge)` `                        ``cc--;` `                ``}` `            ``}` `        ``}`   `        ``return` `cc;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{`   `        ``int``[, ] arr = ``new` `int``[3, 2] { { 73, -62 },` `                                      ``{ 2, 2 },` `                                      ``{ 3, 3 } };` `        ``int` `N = 3;` `        ``int` `M = 2;` `        ``int` `K = 1;` `        ``int` `result = solve(arr, K, N, M);`   `        ``// Function Call` `        ``Console.Write(result);` `    ``}` `}`   `// This code is contributed by garg28harsh.`

Javascript

 ``

Output

`3`

Time Complexity: O(N2), where N is the number of points in the given array.
Auxiliary Space: O(N), for storing the parents and rank array in UnionFind.

My Personal Notes arrow_drop_up
Related Articles