About the pattern
- find(node): Find the representative of the set containing the node.
- union(node1, node2): Merges the set containing node1 and node 2 into one.
- Do union(0, 1): This will merge nodes 0 and 1 together. Change the representative of 0 to 1.
- Similarly do
- union(1,2)
- union(2,3)
- union(4,5): Notice how we merged 4 and 5 instead of 3 and 4. This is done just to give you an idea that an element can merge into any disjoint sets based on the property under consideration.
- union(3,5)
As you would have imagined by now as you are making this disjoint set the size of the tree can be O(N) in the worst case and so is the time complexity of this pattern.
Using 'Union find' pattern
- 1<=n<=1000
- 0<=edges.length<=500
- edges[I].length == 2
- 0<=x,y<n
- x!=y
- No repeated edges
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class UnionFind: def __init__(self, n): self.parent = [] for i in range(n): self.parent.append(i) self.rank = [ 1 ] * n self.connected_components = n def find(self, v): if self.parent[v] != v: return self.find(self.parent[v]) return v def union(self, x, y): p1, p2 = self.find(x), self.find(y) if p1 != p2: if self.rank[p1] < self.rank[p2]: self.parent[p1] = p2 else : self.parent[p2] = p1 self.connected_components = self.connected_components - 1 def count_components(n, edges): uf = UnionFind(n) for edge in edges: v1 = edge[ 0 ] v2 = edge[ 1 ] uf.union(v1, v2) return uf.connected_components |
- Input: 5 , [[0,1],[1,2],[3,4]]
- Output: 2
- Input: 6 , [[0,1],[3,4],[4,5]]
- Output: 3
- parent - list that tracks the parent of each element
- rank - list that tracks the rank of each element
- connected_component - number of connected component