Union Find Disjoint Set Data Structure in DSA Rust - Time & Space Complexity
We want to understand how fast the Union Find data structure works when connecting and checking groups.
How does the time needed change as we add more items?
Analyze the time complexity of the following code snippet.
struct UnionFind {
parent: Vec<usize>,
rank: Vec<usize>,
}
impl UnionFind {
fn find(&mut self, x: usize) -> usize {
if self.parent[x] != x {
self.parent[x] = self.find(self.parent[x]);
}
self.parent[x]
}
fn union(&mut self, x: usize, y: usize) {
let root_x = self.find(x);
let root_y = self.find(y);
if root_x != root_y {
if self.rank[root_x] < self.rank[root_y] {
self.parent[root_x] = root_y;
} else if self.rank[root_x] > self.rank[root_y] {
self.parent[root_y] = root_x;
} else {
self.parent[root_y] = root_x;
self.rank[root_x] += 1;
}
}
}
}
This code manages groups of connected items, letting us quickly find which group an item belongs to and join two groups.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
findfunction uses recursion to find the group's leader and compress paths. - How many times: Each
findcall may recurse up the tree, but path compression makes future calls faster.
As we add more items, the time to find or union grows very slowly because the structure keeps trees shallow.
| Input Size (n) | Approx. Operations per find/union |
|---|---|
| 10 | About 3-4 steps |
| 100 | About 5-6 steps |
| 1000 | About 7-8 steps |
Pattern observation: The steps grow very slowly, almost like a flat line, even as input grows large.
Time Complexity: O(α(n)) (Inverse Ackermann function)
This means each operation takes almost constant time, even for very large inputs.
[X] Wrong: "Each find or union takes linear time because it may traverse many parents."
[OK] Correct: Path compression and union by rank keep trees very flat, so traversals are extremely short on average.
Understanding this time complexity shows you can explain why Union Find is efficient and suitable for grouping problems, a common interview topic.
"What if we removed path compression from find? How would the time complexity change?"
Practice
Union Find Disjoint Set data structure?Solution
Step 1: Understand the role of Union Find
The Union Find data structure is designed to keep track of which elements belong to which groups or sets, especially when these groups merge.Step 2: Compare with other data structures
Sorting, key-value storage, and priority queues serve different purposes unrelated to grouping connected components.Final Answer:
To efficiently track and merge groups of connected elements -> Option BQuick Check:
Union Find = Group tracking [OK]
- Confusing Union Find with sorting algorithms
- Thinking it stores key-value pairs
- Mixing it up with priority queues
union_find crate?Solution
Step 1: Recall Rust struct instantiation
In Rust, constructors are usually implemented as associated functions namednew, called with::new().Step 2: Check common method names
Methods likecreate,init, or usingnewas a keyword are not standard Rust patterns.Final Answer:
let uf = UnionFind::new(5); -> Option DQuick Check:
Rust constructors use ::new() [OK]
- Using 'new' as a keyword instead of method
- Using non-standard method names like create or init
- Incorrect syntax like missing 'let' or wrong function call
let mut uf = UnionFind::new(4);
uf.union(0, 1);
uf.union(2, 3);
let connected = uf.equiv(1, 3);
println!("{}", connected);What is the printed output?
Solution
Step 1: Analyze union operations
Elements 0 and 1 are connected, and elements 2 and 3 are connected, but these two groups are separate.Step 2: Check equivalence of 1 and 3
Since 1 is in the first group and 3 in the second, they are not connected, souf.equiv(1, 3)returns false.Final Answer:
false -> Option AQuick Check:
Groups: {0,1} and {2,3}, 1 and 3 not connected [OK]
- Assuming union connects all elements globally
- Confusing union with adding elements
- Expecting true without checking groups
let mut uf = UnionFind::new(3); uf.union(0, 1); uf.union(1, 3);
Solution
Step 1: Check the size of Union Find
The Union Find is created for 3 elements indexed 0, 1, and 2.Step 2: Analyze union calls
The calluf.union(1, 3)tries to access element 3, which is out of range and causes an index error.Final Answer:
Index out of bounds error due to invalid element 3 -> Option CQuick Check:
Union Find size 3 means max index 2 [OK]
- Ignoring index range and assuming union works
- Thinking union method syntax is wrong
- Assuming no error occurs with invalid indices
uf.union(0, 1); uf.union(1, 2); uf.union(3, 4); uf.union(4, 5); uf.union(2, 5);
How many distinct groups remain?
Solution
Step 1: Track unions step-by-step
Union(0,1) connects 0 and 1; Union(1,2) connects 2 to that group; Union(3,4) connects 3 and 4; Union(4,5) connects 5 to that group.Step 2: Final union merges groups
Union(2,5) connects the group {0,1,2} with {3,4,5}, merging all into one group.Final Answer:
1 -> Option AQuick Check:
All elements connected after last union [OK]
- Counting groups before last union
- Not merging transitive connections
- Assuming unions only connect pairs, not groups
Ready to prove it?
Pass the test and this pattern moves unknown
