最近在复习并查集,所以做了下这个题,这个题用bfs或dfs也是能做的,不过这里只讲一讲quick-union方法。显然,对于各个城市,我们用union函数将有直接或者间接联系的两个城市连接起来,前面这部分我倒是写对了,只是在计算省份数量多时候没有彻底搞清楚,要知道UF这个字典里存的是其父节点而非最祖先的根节点,因此在计算连通分量的时候,应该计算对于所有UF里的键值对键和值想等的情况。这个算法的时间复杂度是O(N^2logN),空间复杂度是O(N)。注意目前并没有使用按秩排序,而2是在union函数中使用了按秩排序的。
python:
class Solution:
def findCircleNum1(self, isConnected: List[List[int]]) -> int:
uf = dict()
def find(x):
uf.setdefault(x, x)
if uf[x] != x:
uf[x] = find(uf[x])
return uf[x]
def union(x, y):
uf[find(x)] = find(y)
if not isConnected:
return 0
prov = len(isConnected)
for i in range(prov):
for j in range(i, prov):
if isConnected[i][j] == 1:
union(i, j)
print(uf)
res = 0
for k, v in uf.items():
res += 1 if k == v else 0
return res
def findCircleNum2(self, isConnected: List[List[int]]) -> int:
rank = dict()
uf = dict()
def find(x):
uf.setdefault(x, x)
if uf[x] != x:
uf[x] = find(uf[x])
return uf[x]
def union(x, y):
x_par, y_par = find(x), find(y)
if x_par == y_par:
return
if rank.setdefault(x, 1) < rank.setdefault(y_par, 1):
uf[x_par] = y_par
rank[y_par] += rank[x_par]
else:
uf[y_par] = x_par
rank[x_par] += rank[y_par]
if not isConnected:
return 0
prov = len(isConnected)
for i in range(prov):
for j in range(i, prov):
if isConnected[i][j] == 1:
union(i, j)
print(uf)
res = 0
for k, v in uf.items():
res += 1 if k == v else 0
return res
PREVIOUSlc202.快乐数
NEXTlc712.账户合并