Skip to content

Commit 68baacf

Browse files
committed
feat: solve DaleStudy#263 with python
1 parent 095786f commit 68baacf

File tree

1 file changed

+77
-0
lines changed
  • number-of-connected-components-in-an-undirected-graph

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from typing import List
2+
from unittest import TestCase, main
3+
4+
5+
class ListNode:
6+
def __init__(self, val=0, next=None):
7+
self.val = val
8+
self.next = next
9+
10+
11+
class Solution:
12+
def countComponents(self, n: int, edges: List[List[int]]) -> int:
13+
return self.solve_union_find(n, edges)
14+
15+
"""
16+
LintCode 로그인이 안되어서 https://neetcode.io/problems/valid-tree에서 실행시키고 통과만 확인했습니다.
17+
18+
Runtime: ? ms (Beats ?%)
19+
Time Complexity: O(max(m, n))
20+
- UnionFind의 parent 생성에 O(n)
21+
- edges 조회에 O(m)
22+
- Union-find 알고리즘의 union을 매 조회마다 사용하므로, * O(α(n)) (α는 아커만 함수의 역함수)
23+
- UnionFind의 각 노드의 부모를 찾기 위해, n번 find에 O(n * α(n))
24+
> O(n) + O(m * α(n)) + O(n * α(n)) ~= O(max(m, n) * α(n)) ~= O(max(m, n)) (∵ α(n) ~= C)
25+
26+
Memory: ? MB (Beats ?%)
27+
Space Complexity: O(n)
28+
- UnionFind의 parent와 rank가 크기가 n인 리스트이므로, O(n) + O(n)
29+
> O(n) + O(n) ~= O(n)
30+
"""
31+
32+
def solve_union_find(self, n: int, edges: List[List[int]]) -> int:
33+
34+
class UnionFind:
35+
def __init__(self, size: int):
36+
self.parent = [i for i in range(size)]
37+
self.rank = [1] * size
38+
39+
def union(self, first: int, second: int):
40+
first_parent, second_parent = self.find(first), self.find(second)
41+
42+
if self.rank[first_parent] > self.rank[second_parent]:
43+
self.parent[second_parent] = first_parent
44+
elif self.rank[first_parent] < self.rank[second_parent]:
45+
self.parent[first_parent] = second_parent
46+
else:
47+
self.parent[second_parent] = first_parent
48+
self.rank[first_parent] += 1
49+
50+
def find(self, node: int):
51+
if self.parent[node] != node:
52+
self.parent[node] = self.find(self.parent[node])
53+
54+
return self.parent[node]
55+
56+
union_find = UnionFind(size=n)
57+
for first, second in edges:
58+
union_find.union(first, second)
59+
60+
result = set()
61+
for i in range(n):
62+
result.add(union_find.find(i))
63+
64+
return len(result)
65+
66+
67+
class _LeetCodeTestCases(TestCase):
68+
def test_1(self):
69+
n = 5
70+
edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
71+
output = False
72+
73+
self.assertEqual(Solution().countComponents(n, edges), output)
74+
75+
76+
if __name__ == '__main__':
77+
main()

0 commit comments

Comments
 (0)