Path Compression in Union Find in DSA Java - Time & Space Complexity
We want to understand how fast the "find" operation runs when we use path compression in Union Find.
Specifically, how does the time grow as we have more elements and unions?
Analyze the time complexity of the following code snippet.
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
This code finds the root of element x and compresses the path to speed up future finds.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls to find until reaching the root.
- How many times: At most once per node on the path from x to root, but path compression shortens future calls.
Initially, paths can be long, so find may take several steps. But path compression flattens the tree, making future finds faster.
| Input Size (n) | Approx. Operations per find |
|---|---|
| 10 | About 2-3 steps on average |
| 100 | About 4-5 steps initially, fewer after compression |
| 1000 | About 5-6 steps initially, very few after compression |
Pattern observation: The number of steps grows very slowly and flattens quickly due to path compression.
Time Complexity: O(α(n)) (Inverse Ackermann function)
This means each find runs almost in constant time for all practical input sizes.
[X] Wrong: "Find with path compression is O(n) because it uses recursion and can visit many nodes."
[OK] Correct: Path compression flattens the tree so future finds are much faster, making the average cost almost constant, not linear.
Understanding path compression's time complexity shows you know how to make Union Find efficient, a key skill in many graph and connectivity problems.
"What if we removed path compression and only used union by rank? How would the time complexity of find change?"
Practice
path compression in the Union Find data structure?Solution
Step 1: Understand the role of path compression
Path compression is used during thefindoperation to make future queries faster by making nodes point directly to the root.Step 2: Identify the effect on the tree structure
This flattens the tree, reducing the height and speeding up subsequentfindcalls.Final Answer:
To speed up thefindoperation by flattening the tree structure -> Option BQuick Check:
Path compression = flatten tree for faster find [OK]
- Confusing path compression with union by size/rank
- Thinking it merges sets instead of optimizing find
- Assuming it initializes data structures
find function implementing path compression in Union Find?Solution
Step 1: Understand the return type of find
Thefindmethod returns the representative (root) of the set containing elementx, so it returns an integer.Step 2: Check method parameters
The method must accept the elementxas input to find its root.Final Answer:
public int find(int x) -> Option AQuick Check:
find returns root index as int [OK]
- Using void return type for find
- Missing parameter for element to find
- Returning boolean instead of int
int[] parent = {0, 0, 1, 2, 3};
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
System.out.println(find(4));
System.out.println(Arrays.toString(parent));
What is the output?Solution
Step 1: Trace find(4) call with path compression
parent[4]=3 -> find(3); parent[3]=2 -> find(2); parent[2]=1 -> find(1); parent[1]=0 -> find(0)=0 (base); parent[1]=0; parent[2]=0; parent[3]=0; parent[4]=0. Returns 0.Step 2: Update parent array after path compression
Entire path flattens: parent = [0, 0, 0, 0, 0].Final Answer:
0 [0, 0, 0, 0, 0] -> Option CQuick Check:
find(4) = 0, all path nodes point to root 0 [OK]
- Thinking only leaf updates (partial compression)
- Expecting no change in parent array
- Misreading recursion depth or base case
find method is intended to implement path compression but has a bug:
int find(int x) {
if (parent[x] == x) {
return x;
}
return find(parent[x]);
}
What is the bug and how to fix it?Solution
Step 1: Identify missing path compression step
The method recursively finds the root but does not updateparent[x]to root, so no path compression happens.Step 2: Fix by assigning compressed parent
Addingparent[x] = find(parent[x]);before returning compresses the path.Final Answer:
Missing path compression assignment; fix by addingparent[x] = find(parent[x]);-> Option AQuick Check:
Assign parent[x] = find(parent[x]) for compression [OK]
- Forgetting to update parent[x]
- Changing base case incorrectly
- Returning void instead of int
parent = {0, 0, 1, 2, 4, 5} and rank = {0, 1, 2, 3, 4, 5}, after performing union(4, 5) and then find(5) with path compression, what will be the updated parent array?Solution
Step 1: Perform union(4, 5) by rank
Ranks: rank[4]=4, rank[5]=5. Since rank[5] > rank[4], parent[4] = 5. But ranks given are increasing, so actually rank[5] is highest, so parent[4] = 5.Step 2: Perform find(5) with path compression
find(5) returns 5 (root). Path compression updates parent of 5 to itself (no change). But parent[4] points to 5, so parent array is [0,0,1,2,5,5].Step 3: Check options
[0, 0, 1, 2, 4, 4] shows parent[5] = 4, which contradicts union by rank. [0, 0, 1, 2, 3, 4] no change. [0, 0, 1, 2, 3, 3] parent[5]=3 incorrect. [0, 0, 1, 2, 5, 5] parent[4]=5 and parent[5]=5 matches expected.Final Answer:
[0, 0, 1, 2, 5, 5] -> Option DQuick Check:
Union by rank sets parent of lower rank to higher [OK]
- Confusing which parent to update in union
- Ignoring rank comparison
- Assuming parent array unchanged after union
Ready to prove it?
Pass the test and this pattern moves unknown
