Challenge - 5 Problems
Union Find Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediateOutput of Union Find after unions
What is the output of the following C++ code that performs union operations on a Union Find data structure?
DSA C++
#include <iostream> #include <vector> using namespace std; class UnionFind { public: vector<int> parent, rank; UnionFind(int n) { parent.resize(n); rank.resize(n, 0); for (int i = 0; i < n; i++) parent[i] = i; } int find(int x) { if (parent[x] != x) parent[x] = find(parent[x]); return parent[x]; } void unite(int x, int y) { int rx = find(x); int ry = find(y); if (rx != ry) { if (rank[rx] < rank[ry]) parent[rx] = ry; else if (rank[ry] < rank[rx]) parent[ry] = rx; else { parent[ry] = rx; rank[rx]++; } } } }; int main() { UnionFind uf(5); uf.unite(0, 1); uf.unite(1, 2); uf.unite(3, 4); for (int i = 0; i < 5; i++) cout << uf.find(i) << " "; return 0; }
Attempts:
2 left
💡 Hint
Remember that union by rank attaches the smaller tree under the root of the deeper tree.
✗ Incorrect
The union operations connect 0,1,2 into one set with root 0, and 3,4 into another set with root 3. The find function returns the root parent for each element.
🧠 Conceptual
intermediateNumber of sets after unions
Given a Union Find data structure initialized with 6 elements (0 to 5), after performing unite(0,1), unite(2,3), unite(4,5), how many disjoint sets remain?
Attempts:
2 left
💡 Hint
Each unite operation merges two sets into one.
✗ Incorrect
Initially, there are 6 sets. Each unite merges two sets, so after 3 unions, 3 sets remain.
🔧 Debug
advancedIdentify the error in Union Find implementation
What error will the following Union Find code produce when calling unite(0,1)?
DSA C++
#include <vector> using namespace std; class UnionFind { public: vector<int> parent; UnionFind(int n) { parent.resize(n); for (int i = 0; i < n; i++) parent[i] = i; } int find(int x) { if (parent[x] != x) return find(parent[x]); return x; } void unite(int x, int y) { int rx = find(x); int ry = find(y); if (rx != ry) { parent[rx] = ry; } } }; int main() { UnionFind uf(2); uf.unite(0, 1); return 0; }
Attempts:
2 left
💡 Hint
Check if the find function terminates correctly.
✗ Incorrect
The find function correctly returns the root and terminates. The unite function updates parent correctly. No error occurs.
❓ Predict Output
advancedOutput after path compression
What is the output of the following code after path compression is applied?
DSA C++
#include <iostream> #include <vector> using namespace std; class UnionFind { public: vector<int> parent; UnionFind(int n) { parent.resize(n); for (int i = 0; i < n; i++) parent[i] = i; } int find(int x) { if (parent[x] != x) parent[x] = find(parent[x]); return parent[x]; } void unite(int x, int y) { int rx = find(x); int ry = find(y); if (rx != ry) parent[ry] = rx; } }; int main() { UnionFind uf(5); uf.parent = {0, 0, 1, 2, 3}; uf.find(4); for (int i = 0; i < 5; i++) cout << uf.parent[i] << " "; return 0; }
Attempts:
2 left
💡 Hint
Path compression updates all nodes on the path to point directly to the root.
✗ Incorrect
Initially, parent array is {0,0,1,2,3}. Calling find(4) compresses path: 4->3->2->1->0, so all become 0.
🧠 Conceptual
expertTime complexity of Union Find operations
What is the amortized time complexity of performing m union/find operations on n elements using Union Find with union by rank and path compression?
Attempts:
2 left
💡 Hint
The inverse Ackermann function grows extremely slowly, almost constant for all practical n.
✗ Incorrect
With union by rank and path compression, the amortized time per operation is almost constant, specifically O(α(n)) where α is the inverse Ackermann function.
