题解
思路
代码
class Solution:
### 0107 深度优先遍历(64 ms,15.5 MB)
def findCircleNum(self, isConnected: List[List[int]]) -> int:
# 定义深度递归函数
def dfs(i):
for j in range(n):
# 搜索与该城市直接连接的城市,并从被连接的城市继续深度递归
if isConnected[i][j] == 1 and j not in visited:
visited.add(j) # 记录被访问的城市
dfs(j)
# 定义城市数量,访问集合,连通分量数量
n, visited, cnt = len(isConnected), set(), 0
# 遍历每一个城市
for i in range(n):
# 若此城市未被访问,则对其进行深度递归,且连通分量数加一
# 因为属于同一连通分量的城市已经被访问完毕
if i not in visited:
dfs(i)
cnt += 1
return cnt
### 0107 广度优先遍历(152 ms,15.1 MB)
def findCircleNum(self, isConnected: List[List[int]]) -> int:
n, visited, cnt = len(isConnected), set(), 0
# 遍历每一个城市
for i in range(n):
# 若此城市未被访问,则对其进行广度搜索,且连通分量数加一
if i not in visited:
# 新建一个队列用于存储当前城市的邻居城市(即直接相连)
queue = collections.deque([i])
# 若当前队列非空,则搜索并记录其邻居城市
while queue:
j = queue.popleft()
visited.add(j)
# 遍历每一个城市,判断是否是当前城市的邻居城市
for k in range(n):
if isConnected[j][k] == 1 and k not in visited:
queue.append(k) # 注意:这里是j和k!
cnt += 1 # 连通分量数加一
return cnt
### 0107 并查集(56 ms,15.1 MB)
def findCircleNum(self, isConnected: List[List[int]]) -> int:
# 递归寻找index的 根 父节点
def find(index: int) -> int:
if parent[index] != index:
parent[index] = find(parent[index])
return parent[index]
# 合并两个节点,即将其父节点修改为同一个
def union(index1: int, index2: int):
# 将index1的父节点修改为index2的父节点
parent[find(index1)] = find(index2)
provinces = len(isConnected)
# 父节点集合:初始化每个节点的父节点下标为其本身
parent = list(range(provinces))
for i in range(provinces):
for j in range(i + 1, provinces):
# 若两个城市是邻居,则合并这两个城市
if isConnected[i][j] == 1:
union(i, j)
# 连通分量数 = 不同父节点的数量
circles = sum(parent[i] == i for i in range(provinces))
return circles