Given n
nodes labeled from 0
to n - 1
and a list of undirected edges (each edge is a pair of nodes), write a function to find the number of connected components in an undirected graph.
Example 1:
0 3 | | 1 --- 2 4
Given n = 5
and edges = [[0, 1], [1, 2], [3, 4]]
, return 2
.
Example 2:
0 4 | | 1 --- 2 --- 3
Given n = 5
and edges = [[0, 1], [1, 2], [2, 3], [3, 4]]
, return 1
.
Note:
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
根据题意,类似寻找有几个连续在一起的集合。
1. 找到集合。用Union find的思路。
最多的可能性是n组数,全相同,有n个集合。
如果一组数最终找到的id不同,就是说明两个数不在一个集合中,则归入一个集合,可能性少1。
class Solution(object):
def countComponents(self, n, edges):
result = n
temp = range(n) # help list, 用于连接集合和查找index
for edge in edges:
if self.unite(edge[0], edge[1], temp):
result -= 1
return result
def unite(self, start, end, temp):
sid = self.find(start, temp)
eid = self.find(end, temp)
if sid == eid: # 同一个集合
return False
else: # 不同id,连接成一个集合
temp[sid] = eid
return True
def find(self, start, temp):
while temp[start] != start: # 假如不相同,意味着start已经被归入了集合
temp[start] = temp[temp[start]] # 往下深入,寻找最终的id
start = temp[start] #
return start
n = 5 => 有index list: temp [ 0, 1, 2, 3, 4 ]
[ [0, 1], [2, 1], [1, 4], [3, 1] ]
0 & 1 => temp [ 1, 1, 2, 3, 4 ]
2 & 1 => temp [ 1, 1, 1, 3, 4 ]
1 & 4 => temp [ 1, 4, 1, 3, 4 ]
3 & 1 => 此时才会调用find函数中的while loop --> temp[1] = temp[temp[1]] = 4; start = 4 --> temp[4] == 4; 所以返回4. => temp [ 1, 4, 1, 4, 4 ]
因为都连接在一起,所以应该返回result = 1。
======
DFS
class Solution(object):
def countComponents(self, n, edges):
visited = [0] * n # [0, 0, 0, 0]
dic = { x : [] for x in xrange(n)} # {0: [], 1: [], 2: [], 3: []}
for edge in edges:
dic[edge[0]].append(edge[1])
dic[edge[1]].append(edge[0])
result = 0
for i in xrange(n):
if not visited[i]: # 入口,visit 所有相关的id
self.dfs_helper(i, dic, visited)
result += 1
return result
def dfs_helper(self, i, dic, visited):
if visited[i]:
return
visited[i] = 1
for j in dic[i]: # 注意keys的id从0开始。 # 把id为i的所有关联id全部visited一遍
self.dfs_helper(j, dic, visited)
dic = { x : [] for x in xrange(n)} # {0: [], 1: [], 2: [], 3: []}
这样生成的字典是从0开始的。避免了后面的for loop字典可能会产生的KeyError找不到id的错误。
BFS
class Solution(object):
def countComponents(self, n, edges):
visited = [0] * n # [0, 0, 0, 0]
dic = { x : [] for x in xrange(n)} # {0: [], 1: [], 2: [], 3: []}
for edge in edges:
dic[edge[0]].append(edge[1])
dic[edge[1]].append(edge[0])
result = 0
for i in xrange(n):
if not visited[i]: # 入口,visit所有相关的id
result += 1
touched = [i] # 先visit了key的id
while touched:
node = touched.pop(0)
if not visited[node]:
visited[node] = 1
for j in dic[node]:
touched.append(j) # 加上所有的value中的id,继续loop
return result