Union Find Disjoint Set Data Structure in DSA Typescript - Time & Space Complexity
We want to understand how fast the Union Find data structure works when connecting groups and checking if elements belong together.
How does the time needed change as we add more elements and connections?
Analyze the time complexity of the following Union Find operations.
class UnionFind {
parent: number[];
constructor(n: number) {
this.parent = Array.from({ length: n }, (_, i) => i);
}
find(x: number): number {
if (this.parent[x] !== x) {
this.parent[x] = this.find(this.parent[x]);
}
return this.parent[x];
}
union(a: number, b: number): void {
const rootA = this.find(a);
const rootB = this.find(b);
if (rootA !== rootB) this.parent[rootB] = rootA;
}
}
This code creates groups of connected elements and finds which group an element belongs to, using path compression.
Look at the main repeated actions:
- Primary operation: The
findmethod, which follows parent links up to the root. - How many times: Each
unioncallsfindtwice; manyfindcalls happen during unions and checks.
As we add more elements and unions, the time per operation grows very slowly.
| Input Size (n) | Approx. Operations per find/union |
|---|---|
| 10 | About 4 steps |
| 100 | About 5 steps |
| 1000 | About 6 steps |
Pattern observation: The steps grow very slowly, almost like a flat line, thanks to path compression.
Time Complexity: O(α(n)) per operation
This means each find or union runs in almost constant time, where α(n) is a very slow-growing function.
[X] Wrong: "Each find operation takes linear time because it may follow many parents."
[OK] Correct: Path compression flattens the structure, so repeated finds become very fast, not linear.
Understanding Union Find's time complexity shows you can handle efficient grouping problems, a common skill in coding challenges.
"What if we removed path compression from the find method? How would the time complexity change?"
Practice
Union Find Disjoint Set data structure?Solution
Step 1: Understand the data structure's goal
The Union Find Disjoint Set is designed to keep track of which elements belong to which groups or sets, especially when these groups merge.Step 2: Compare options with the purpose
Sorting, key-value storage, and queue operations are unrelated to the main function of Union Find, which is about grouping and merging sets.Final Answer:
To efficiently track and merge groups of connected elements -> Option AQuick Check:
Union Find = Track and merge groups [OK]
- Confusing Union Find with sorting algorithms
- Thinking it stores key-value pairs like a dictionary
- Assuming it works like a queue or stack
Solution
Step 1: Recall TypeScript class instantiation syntax
In TypeScript, to create an instance of a class, we use thenewkeyword followed by the class name and parentheses with arguments.Step 2: Check each option for correct syntax
const uf = new UnionFind(5); usesnew UnionFind(5);which is correct. const uf = UnionFind(5); missesnew. let uf = new UnionFind[]; uses incorrect array syntax. let uf = UnionFind.new(5); uses invalid method call syntax.Final Answer:
const uf = new UnionFind(5); -> Option BQuick Check:
Usenew ClassName(args)to create instance [OK]
- Omitting the 'new' keyword
- Using array syntax instead of class instantiation
- Incorrect method call syntax for constructors
const uf = new UnionFind(5); uf.union(0, 1); uf.union(1, 2); uf.union(3, 4); console.log(uf.connected(0, 2)); console.log(uf.connected(0, 4));What will be the output?
Solution
Step 1: Track unions and connections
Union(0,1) connects 0 and 1. Union(1,2) connects 1 and 2, so 0,1,2 are connected. Union(3,4) connects 3 and 4.Step 2: Check connected queries
connected(0,2) is true because 0 and 2 are in the same set. connected(0,4) is false because 0 and 4 belong to different sets.Final Answer:
true false -> Option AQuick Check:
Connected(0,2) = true, Connected(0,4) = false [OK]
- Assuming all elements are connected initially
- Mixing up union and connected method effects
- Forgetting that union merges sets
find method of a Union Find class but has a bug:
find(x: number): number {
while (this.parent[x] !== x) {
x = this.parent[x];
}
return x;
}
What is the bug and how to fix it?Solution
Step 1: Identify missing optimization in find method
The method correctly finds the root but does not apply path compression, which speeds up future queries by flattening the tree.Step 2: Explain fix with path compression
To fix, recursively find the root and setparent[x]to the root during traversal, e.g.,parent[x] = find(parent[x]).Final Answer:
No path compression; fix by setting parent[x] = find(parent[x]) inside loop -> Option DQuick Check:
Path compression improves find by updating parents [OK]
- Ignoring path compression optimization
- Adding unnecessary break causing incomplete search
- Changing return type incorrectly
- Using wrong equality operator
uf.union(0, 1); uf.union(1, 2); uf.union(3, 4); uf.union(5, 6); uf.union(4, 5); uf.union(2, 6);How many distinct sets remain?
Solution
Step 1: Track unions step-by-step
Union(0,1) connects 0 and 1. Union(1,2) connects 2 to 0,1 group. Union(3,4) connects 3 and 4. Union(5,6) connects 5 and 6. Union(4,5) connects sets {3,4} and {5,6} into one group {3,4,5,6}. Union(2,6) connects {0,1,2} and {3,4,5,6} into one big group {0,1,2,3,4,5,6}.Step 2: Count distinct sets after all unions
All elements are connected into a single set, so only 1 distinct set remains.Final Answer:
1 -> Option CQuick Check:
All unions connect all elements into 1 set [OK]
- Counting sets before all unions complete
- Missing that union(2,6) merges two big sets
- Assuming initial sets remain unchanged
Ready to prove it?
Pass the test and this pattern moves unknown
