放两个模板
模版一:
初始化状态下,每个节点都不在子集合里,根节点的parent是None
class UnionFind:def __init__(self):"""记录每个节点的父节点"""self.father = {}def find(self,x):"""查找根节点路径压缩"""root = xwhile self.father[root] != None:root = self.father[root]# 路径压缩while x != root:original_father = self.father[x]self.father[x] = rootx = original_fatherreturn rootdef merge(self,x,y,val):"""合并两个节点"""root_x,root_y = self.find(x),self.find(y)if root_x != root_y:self.father[root_x] = root_ydef is_connected(self,x,y):"""判断两节点是否相连"""return self.find(x) == self.find(y)def add(self,x):"""添加新节点"""if x not in self.father:self.father[x] = None
模板二:
初始状态下所有节点的parent是他自己,所有没有了add函数,而且在find root函数里判断条件不是parent为None,而是parent为自身
1202. 交换字符串中的元素
class UnionFind:def __init__(self,n):self.parent = [i for i in range(n)]def find(self, x):root = xwhile self.parent[root]!=root:root = self.parent[root]while x!=root:self.parent[x],x, = root ,self.parent[x]return rootdef union(self,x,y):root_x, root_y = self.find(x), self.find(y)if root_x!=root_y:self.parent[root_x]=root_yfrom collections import defaultdictclass Solution:def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:uf = UnionFind(len(s))for i,j in pairs:uf.union(i,j)children = defaultdict(lambda: set())for i,j in pairs:root = children[uf.find(i)]root.add(i)root.add(j)arr = list(s)for v in children.values():for i,j in zip(sorted(v),sorted([arr[i] for i in v])):arr[i]=jreturn "".join(arr)
200. 岛屿数量
https://leetcode-cn.com/problems/number-of-islands/
岛屿的数量还是用DFS写起来好理解一些
1319. 连通网络的操作次数
https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/
- n台计算机至少需要n-1条线才能全部联通
- 用并查集计算有多少个cluster,那么至少需要cluster-1条多余的连接线才可以做到全连通
如何计算多余的线? 其实并不需要计算,因为如果两个cluster之间没有足够的线把他们链接起来,那么就已经不满足第一个条件了
class UnionFind:def __init__(self, n):self.family = [i for i in range(n)]self.redundant = 0def find(self,x):root = xwhile self.family[root]!=root:root = self.family[root]while root!=x:self.family[x], x = root, self.family[x]return rootdef union(self,x,y):root_x, root_y = self.find(x), self.find(y)if root_x!=root_y:self.family[root_x] = root_ydef is_connected(self,x,y):return self.find(x) == self.find(y)class Solution:def makeConnected(self, n: int, connections: List[List[int]]) -> int:if len(connections) < n-1:return -1uf = UnionFind(n)for a,b in connections:if uf.is_connected(a,b):uf.redundant+=1uf.union(a, b)clusters = 0for i in range(n):if uf.family[i]==i:clusters+=1if uf.redundant < clusters-1:return -1else:return clusters-1
