Skip to content

Commit 50791a8

Browse files
committed
add solution: number-of-connected-components-in-an-undirected-graph
1 parent 94106fc commit 50791a8

File tree

1 file changed

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

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'''
2+
# 323. Number of Connected Components in an Undirected Graph
3+
4+
- 무방향 그래프에서 연결된 컴포넌트(connected component)의 개수 구하기
5+
- 노드 개수 n: 0 ~ n-1
6+
- 간선 리스트 edges: 노드 쌍 [u, v]
7+
- 연결된 컴포넌트의 개수를 반환한다.
8+
9+
## 그래프
10+
- edges를 통해 인접 리스트(adjacency list)를 생성한다.
11+
- 무방향 그래프이므로, u ↔ v 양쪽 방향으로 연결
12+
13+
## 풀이 알고리즘
14+
- DFS(스택)/BFS(큐)
15+
- 각 컴포넌트를 탐색하며 방문 처리
16+
- 방문하지 않은 노드를 찾으면 새로운 컴포넌트이므로 카운트 증가
17+
- Union-Find
18+
- 각 노드가 어떤 그룹에 속하는 지 parent 배열로 표현
19+
- find로 부모를 찾고, union으로 노드를 합친다.
20+
- 최종적으로 독립된 그룹의 개수를 반환한다.
21+
'''
22+
23+
'''
24+
1. DFS(스택)
25+
'''
26+
def countComponentsDFS(self, n: int, edges: List[List[int]]) -> int:
27+
graph = defaultdict(list)
28+
for u, v in edges: # 인접 리스트 생성
29+
graph[u].append(v)
30+
graph[v].append(u)
31+
32+
visited = set() # 방문처리할 set
33+
count = 0
34+
35+
def dfs(start):
36+
stack = [start]
37+
visited.add(start)
38+
39+
while stack:
40+
curr = stack.pop()
41+
for neighbor in graph[curr]:
42+
if neighbor not in visited:
43+
visited.add(neighbor)
44+
stack.append(neighbor)
45+
46+
for node in range(n):
47+
if node not in visited:
48+
dfs(node)
49+
count += 1
50+
51+
return count
52+
53+
'''
54+
2. BFS(큐)
55+
'''
56+
def countComponentsBFS(self, n: int, edges: List[List[int]]) -> int:
57+
graph = defaultdict(list)
58+
for u, v in edges: # 인접 리스트 생성
59+
graph[u].append(v)
60+
graph[v].append(u)
61+
62+
visited = set() # 방문처리할 set
63+
count = 0
64+
65+
def bfs(start):
66+
queue = deque([start])
67+
visited.add(start)
68+
69+
while queue:
70+
curr = queue.popleft()
71+
for neighbor in graph[curr]:
72+
if neighbor not in visited:
73+
visited.add(neighbor)
74+
queue.append(neighbor)
75+
76+
for node in range(n):
77+
if node not in visited:
78+
bfs(node)
79+
count += 1
80+
81+
return count
82+
83+
'''
84+
3. Union-Find
85+
- 간선을 순회하며 두 노드를 union으로 합친다.(parent 업데이트)
86+
- find는 경로 압축을 통해 대표(root)를 찾는다.(parent에서 재귀로 찾기)
87+
- 최종 root를 조사하고, 서로 다른 root의 개수를 반환한다.
88+
'''
89+
def countComponentsUnionFind(self, n: int, edges: List[List[int]]) -> int:
90+
parent = list(range(n)) # 각 노드의 부모를 자신으로 초기화
91+
92+
def find(x):
93+
if parent[x] != x:
94+
parent[x] = find(parent[x]) # 경로 압축 path compression
95+
return parent[x]
96+
97+
def union(x, y):
98+
rootX = find(x)
99+
rootY = find(y)
100+
if rootX != rootY:
101+
parent[rootX] = rootY
102+
103+
for u, v in edges:
104+
union(u, v)
105+
106+
# 모든 노드의 최종 부모의, 유일한 root의 개수를 반환
107+
return len(set(find(i) for i in range(n)))

0 commit comments

Comments
 (0)