Union-Find (template)
Each group is a tree of parent pointers, and the root of the tree names the group. connected(x, y) compares find(x) with find(y). union(x, y) links one root under the other, so a union changes exactly one pointer and no node is renamed.
Two nodes are in one group exactly when they have the same root, so find(x) == find(y) is the whole connected check.
Problem
You have n nodes numbered 0 to n − 1. At the start, every node is alone in its own group.
You get a list of queries. Each query is [type, x, y]:
- type
1is a union: join the group ofxwith the group ofy. - type
2asks are x and y connected?: say whetherxandyare in the same group right now. Recordtrueorfalse.
Return the answers to the type-2 queries, in the order they appear.
n, the number of nodes, and queries, a list of [type, x, y] triples.
A list of booleans (vector<bool>): one answer for each type-2 query, in the same order.
After joining 0 and 1, the nodes 0 and 1 are connected, but 2 is still alone. After joining 1 and 2, the group is {0, 1, 2}, so 0 and 2 are connected.
The groups are {0, 1} and {2, 3} when we ask about 0 and 3, so the answer is no. Joining 1 and 3 merges all four nodes, so 0 and 2 are connected.
- • Every node number x and y is in the range 0 to n − 1.
- • The type is 1 (union) or 2 (connected?).
- • A node is always connected to itself.
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
A union changes which nodes share a group. What stays the same for every other group?
- 2.
How could I answer "are x and y connected?" without looking at every node in the group?
- 3.
If every group had one name, what would a union have to rename?
- 4.
If each node stores only one parent, how do I find the group's name from any node in it?
- 5.
When I join two groups, do I attach the two nodes from the query, or something else?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | One label per node; a union renames every node of one group | O(N · Q) | O(N) |
| Optimal | Parent pointers; find each root, link roots (smaller under bigger) | O(Q · α(N)) | O(N) |
Why does this belong to this pattern?
- “groups that merge over time”Items join groups as the queries arrive → keep groups with one root each.
- “type 1: join x and y”A union: merge two groups, and never split them.
- “type 2: are x and y connected?”Compare the roots of the two items; no search over the graph is needed.
This is the base template of the whole pattern. Every later question keeps the same two operations, find and unite, and only changes what an item stands for or when two items are united. Here the nodes are plain numbers and the answers come straight from the roots, with nothing else to count.
Don't make this mistake
Pattern-confusion trap: this looks like a union, but it only works on nodes that are already roots. On the dry run, after union(0, 1) and union(2, 3), node 3 hangs under 2. Then union(1, 3) with the wrong code sets parent[3] = 1. Node 3 leaves its group, so the group {2, 3} is split and connected(2, 3) returns false. With find first, the roots are 0 and 2, so parent[2] = 0 and all four nodes stay together.
parent[x] only points one level up. After union(1, 3) on the dry run, parent[3] = 2 and parent[2] = 0. They differ, yet 2 and 3 are in one group. Always compare the roots.
Always hanging the same side under the other can build a chain 0 ← 1 ← 2 ← … ← n−1. Then find walks n steps every time. The size rule keeps trees shallow, so every find stays short.
Want to implement this?
Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Union-Find (DSU) translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.