पाठ 22 / 42
Union-Find / Disjoint Set
एक structure जो अलग-अलग समूहों को track करता है और 'एक ही समूह?' व 'समूह मिलाएँ' को लगभग O(1) में उत्तर देता है।
समूह, trees के रूप में
Union-Find (Disjoint Set Union) हर समूह को एक tree के रूप में दिखाता है, जहाँ हर node एक parent की ओर इशारा करता है, और root अपना ही parent होता है। find(x), x का समूह पहचानने के लिए root तक जाता है; union(x, y) एक root को दूसरे के नीचे जोड़ता है।
Path compression + union by rank
दो optimizations इसे लगभग constant time बना देते हैं: path compression find के दौरान tree को चपटा करता है, और union by rank छोटे tree को बड़े के नीचे जोड़ता है।
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # path compression
return self.parent[x]
def union(self, x, y):
rx, ry = self.find(x), self.find(y)
if rx == ry:
return False
if self.rank[rx] < self.rank[ry]:
rx, ry = ry, rx
self.parent[ry] = rx
if self.rank[rx] == self.rank[ry]:
self.rank[rx] += 1
return True
Output:
uf = UnionFind(5) uf.union(0, 1) uf.find(0) == uf.find(1) # True
कहाँ इस्तेमाल होता है
Undirected graph में cycle पहचानना, Kruskal's MST, connected components गिनना, और 'friend circles' जैसी समस्याएँ — सब Union-Find पर निर्भर करती हैं।
त्वरित जांच
Amortized complexity की समझ परखें।
त्वरित जाँच: Path compression और union by rank के साथ, find/union लगभग चलते हैं:
- O(n)
- O(log n)
- O(n log n)
- लगभग O(1) (inverse-Ackermann)
Answer
लगभग O(1) (inverse-Ackermann) — Amortized complexity O(α(n)) है, inverse Ackermann function, जो किसी भी वास्तविक n के लिए प्रभावी रूप से स्थिर है।