Path Compression in Union Find in DSA Typescript - Time & Space Complexity
We want to understand how fast the "find" operation runs when using path compression in Union Find.
How does the time to find the root change as we do more operations?
Analyze the time complexity of the following find function with path compression.
function find(parent: number[], x: number): number {
if (parent[x] !== x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
This code finds the root of element x and flattens the path to speed up future finds.
Look for loops or recursion that repeat work.
- Primary operation: Recursive calls to find following parent links.
- How many times: Up to the height of the tree before compression.
Initially, the tree can be tall, so find may take many steps. But path compression flattens it fast.
| Input Size (n) | Approx. Operations per find |
|---|---|
| 10 | About 2-3 steps after some finds |
| 100 | About 4-5 steps initially, fewer after compression |
| 1000 | Starts higher but quickly flattens to near 1 step |
Pattern observation: The steps grow very slowly and almost stay constant after many finds.
Time Complexity: O(α(n))
This means each find runs in almost constant time, where α(n) is a very slow growing function (the inverse Ackermann function).
[X] Wrong: "Find always takes time proportional to the height of the tree."
[OK] Correct: Path compression flattens the tree so future finds become much faster, making the average cost almost constant.
Understanding path compression's time complexity shows you can analyze clever optimizations that make algorithms very efficient in practice.
What if we removed path compression? How would the time complexity of find change?
Practice
path compression in a Union Find data structure?Solution
Step 1: Understand the find operation
Thefindoperation locates the root of an element's set in Union Find.Step 2: Role of path compression
Path compression flattens the tree by making nodes point directly to the root, speeding up futurefindcalls.Final Answer:
To speed up thefindoperation by flattening the tree -> Option BQuick Check:
Path compression = faster find [OK]
- Confusing path compression with union operation
- Thinking it deletes elements
- Assuming it sorts elements
find function with path compression in Union Find?Solution
Step 1: Identify path compression in code
Path compression updatesparent[x]to root during recursion.Step 2: Check each option
function find(x: number): number { if (parent[x] !== x) parent[x] = find(parent[x]); return parent[x]; } updatesparent[x]recursively, implementing path compression correctly.Final Answer:
function find(x: number): number { if (parent[x] !== x) parent[x] = find(parent[x]); return parent[x]; } -> Option AQuick Check:
Path compression updates parent[x] recursively [OK]
- Missing parent update for path compression
- Using loop without updating parent
- Returning without compression
console.log(parent) after calling find(3)?
let parent = [0, 0, 1, 2, 4];
function find(x: number): number {
if (parent[x] !== x) parent[x] = find(parent[x]);
return parent[x];
}
find(3);
console.log(parent);Solution
Step 1: Trace find(3) calls
find(3) checks parent[3] = 2, calls find(2). find(2) checks parent[2] = 1, calls find(1). find(1) checks parent[1] = 0, calls find(0). find(0) returns 0 since parent[0] = 0.Step 2: Apply path compression updates
Unwinding: parent[1] = 0 (already), returns 0; parent[2] = 0, returns 0; parent[3] = 0, returns 0. Final parent = [0, 0, 0, 0, 4].Final Answer:
[0, 0, 0, 0, 4] -> Option DQuick Check:
Path compression sets all path nodes to root [OK]
- Not updating parent array after recursion
- Confusing indices and values
- Assuming all parents become root immediately
find function implementing path compression:
function find(x: number): number {
if (parent[x] === x) return x;
find(parent[x]);
return parent[x];
}Solution
Step 1: Analyze recursion and return
The function callsfind(parent[x])but does not assign its result back toparent[x].Step 2: Identify missing path compression update
Withoutparent[x] = find(parent[x]), path compression does not happen, so the tree is not flattened.Final Answer:
Missing assignment toparent[x]for path compression -> Option AQuick Check:
Path compression requires updating parent[x] [OK]
- Forgetting to assign recursive call result
- Returning without recursion
- Wrong base case logic
parent = [0, 0, 1, 2, 3, 5]. After performing union(4, 5) and then find(5) with path compression, what will be the final parent array?Solution
Step 1: Perform union(4, 5)
Initial parent = [0, 0, 1, 2, 3, 5]. Simple union links by setting parent[5] = 4. Now parent = [0, 0, 1, 2, 3, 4].Step 2: Call find(5) with path compression
find(5): parent[5]=4 -> find(4): parent[4]=3 -> find(3)=2 -> find(2)=1 -> find(1)=0 -> find(0)=0.Step 3: Update parent array after compression
Unwinding sets parent[4]=0, parent[3]=0, parent[2]=0, parent[1]=0, but parent[5] remains 4 because find(5) returns 0 but parent[5] was set to 4 and not updated in this code snippet. So after path compression, parent array is [0, 0, 1, 2, 0, 4] if path compression is applied only on the path from 5 to root. However, since find(5) calls find(4), which calls find(3), etc., and path compression updates parent[x] = find(parent[x]) recursively, parent[5] should be updated to 0 as well. So final parent array is [0, 0, 0, 0, 0, 0].Final Answer:
[0, 0, 0, 0, 0, 0] -> Option CQuick Check:
Union sets and compress path update parents [OK]
- Not updating parent after union
- Ignoring path compression updates
- Assuming parent stays same after find
Ready to prove it?
Pass the test and this pattern moves unknown
