题目描述:
参考地址:
https://www.cnblogs.com/grandyang/p/6686983.html
https://blog.csdn.net/niushuai666/article/details/6662911
有个班级,里面有N个学生,他们之中有些是朋友有些不是,比如如果A是B的朋友,B是C的朋友,那么A就是C的间接朋友,我们定义所谓的朋友圈就是由直系和间接朋友所组成的群体。
给定一个N*N的矩阵M,代表这个班级里所有学生的朋友关系,如果M[i][j] = 1,那么第i个和第j个学生就是互为直系朋友,不为1的话就不是朋友。而你的任务就是输出整个班级里总的朋友圈数量。
代码:方法一DFS
class Solution:
def findCircleNum(self, M: List[List[int]]) -> int:
res = 0
m, n = len(M), len(M[0])
v = [False] * m
for i in range(m):
if v[i]:
continue
self.helper(M, i, v)
res += 1
return(res)
def helper(self, M, k, v):
v[k] = True
for i in range(len(M)):
if (not M[k][i]) or v[i]:
continue
self.helper(M, i, v)
代码:方法二:BFS
class Solution:
def findCircleNum(self, M: List[List[int]]) -> int:
if M == [] or M[0] == []:
return 0
n = len(M)
visited = [False] * n
counter = 0
for i in range(n):
if not visited[i]:
queue = [i]
while queue:
index = queue.pop(0)
visited[index] = True
for j in range(n):
if M[index][j] and not visited[j]:
queue.append(j)
counter += 1
return counter
方法三:并查集
class Solution:
def findCircleNum(self, M: List[List[int]]) -> int:
m = len(M)
res = m
root = []
for i in range(m):
root.append(i)
for i in range(m):
for j in range(m):
if M[i][j] == 1:
p1 = self.get_root(root, i)
p2 = self.get_root(root, j)
if p1 != p2:
res -= 1
root[p2] = p1
return res
#root存的是属于同一组的另一个对象的坐标,这样通过getRoot函数可以使同一个组的对象返回相同的值
def get_root(self, root, i):
while i != root[i]:
i = root[i]
return i