45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
# Time: O(E · 𝛼(n)) ; 𝛼(n) is inverse Ackermann function
|
||
# Space: O(V)
|
||
|
||
|
||
class Solution:
|
||
def countComponents(self, n: int, edges: List[List[int]]) -> int:
|
||
parent = [i for i in range(n)]
|
||
|
||
# Or like sizes of the components
|
||
rank = [1] * n
|
||
|
||
def find(node):
|
||
# Parent of node could be itself (i.e, no parent)
|
||
current_node = node
|
||
|
||
while current_node != parent[current_node]:
|
||
# Path compression to speed up union-find
|
||
parent[current_node] = parent[parent[current_node]]
|
||
current_node = parent[current_node]
|
||
|
||
return current_node
|
||
|
||
|
||
def union(a, b):
|
||
parent_a, parent_b = find(a), find(b)
|
||
|
||
if parent_a == parent_b:
|
||
return 0
|
||
|
||
if rank[parent_a] > rank[parent_b]:
|
||
parent[parent_a] = parent_b
|
||
rank[parent_b] += rank[parent_a]
|
||
else:
|
||
parent[parent_b] = parent_a
|
||
rank[parent_a] += rank[parent_b]
|
||
|
||
return 1
|
||
|
||
|
||
result = n
|
||
for a, b in edges:
|
||
result -= union(a, b)
|
||
|
||
return result
|
||
|