Skip to main content

Union and Find

This page provides introduction to union and find data structure.

Overview

Union and find is a data structure used to efficiently manage a collection of disjoint sets and supports two main operations:

  • Union: Merges two sets into one.
  • Find: Determines which set a particular element is in.

Build Union and Find

Let's build a union and find data structure for below disjoint group:

union-and-find-1.svg

We represent all relationships in disjoint groups using the union and find data structure. To achieve this, we first determine the parent of each node by tracing the values in the array until we find a node that points to itself. Once the parents are identified, we unify the groups by assigning the parent of one node to the other.

Initially, we set the parent of each node to itself.

union-and-find-2.svg

Node 00 is connected to node 11. The parent of 00 is 00, and the parent of 11 is 11. Therefore we update the parent of 11 to be 00 to represent the connection.

union-and-find-3.svg

Node 00 is connected to node 33. The parent of 00 is 00, and the parent of 33 is 33. Therefore we update the parent of 33 to be 00 to represent the connection.

union-and-find-4.svg

Node 11 is connected to node 00. The parent of 00 is 00, and the parent of 11 is 00, here no updates are required and node 00 and 11 belong to same group.

Node 11 is connected to node 22. The parent of 11 is 00, and the parent of 22 is 22. Therefore we update the parent of 22 to be 00 to represent the connection.

union-and-find-5.svg

Similarly, we explore all connections from node 22 and 33 to get the same result as above image.

Next we explore all connections from node 44. The parent of 44 is 4040, and the parent of 55 is 55. Therefore we update the parent of 55 to be 44 to represent the connection.

union-and-find-6.svg

Similarly, we explore all the connections from node 55 to get the same result as above image.

Finally, we visit node 66, which has no connections, and our union-find data structure is complete, representing 33 disjoint groups.

union-and-find-7.svg
class UnionAndFind {
int[] parentArr;

UnionAndFind(int nodes) {
this.parentArr = new int[nodes];
for(int i = 0; i < nodes; i++) {
parentArr[i] = i;
}
}

public void union(int from, int to) {
int fromParent = find(from);
int toParent = find(to);
if(fromParent != toParent) parentArr[fromParent] = toParent;
}

public int find(int node) {
if(parentArr[node] == node) return node;
int parent = parentArr[node];
/**
* Path compression: Since we have already calculated the parent for this node,
* we can directly update it in the parent array.
* This helps reduce the time required for future queries.
*/
return parentArr[parent] = find(parent);
}
}

Complexity

Let's say there are N\text{N} elements in an array.

Time Complexity

The time complexity for find is:

O(α(N))\text{O}(\alpha\text{(N))}

Where, α(N)\alpha\text{(N)} is the inverse Ackermann function.

info

The Ackermann function grows extremely slowly, and for practical purposes, α(N)\alpha\text{(N)} is close to a constant value Thus, the find operation is nearly constant time in practice O(1)\text{O(1)} for most cases.

It requires at most one find operation for each of the two sets being merged therefore the time complexity for union is:

O(α(N))\text{O}(\alpha\text{(N))}

Space Complexity

The space is required to store the parent pointers of each element, therefore space complexity is:

O(N)\text{O(N)}

Leetcode Problem Set