classUnion_Find(): def__init__(self, n): """Initialize a list of length n: n nodes as index and root as value, count: the number of disjoint set""" pass
defis_connected(self, p: int, q: int)->bool: """decide if p and q are in the same disjoint set """ pass defunion(self, p: int, q: int): """connect node p and node q """ pass deffind(self, p:int)->int: """find the root of p""" pass
# quick-find classUnion_Find(): def__init__(self, n: int): """Initialize a list: Nodes as index and root as value, count: the number of disjoint set, """ self.len = n self.uf = [i for i inrange(self.len)] self.count = n
deffind(self, p:int)->int: """find the root of p""" return self.uf[p]
defis_connected(self, p: int, q: int)->bool: """decide if p and q are in the same disjoint set """ return self.find(p) == self.find(q)
defunion(self, p: int, q: int): """connect node p and node q """ if self.is_connected(p, q): return p_root, q_root = self.find(p), self.find(q) for i inrange(self.len): if self.find(i) == p_root: self.uf[i] = q_root self.count -= 1
# quick-union classUnion_Find(): def__init__(self, n: int): """Initialize a list: Nodes as index and root as value, count: the number of disjoint set, """ self.len = n self.uf = [i for i inrange(self.len)] self.count = n
deffind(self, p:int)->int: """find the root of p""" while self.uf[p] != p: p = self.uf[p] return p
defis_connected(self, p: int, q: int)->bool: """decide if p and q are in the same disjoint set """ return self.find(p) == self.find(q)
defunion(self, p: int, q: int): """connect node p and node q """ p_root, q_root = self.find(p), self.find(q) if p_root == q_root: return self.uf[p_root] = q_root self.count -= 1
# weighted-quick-union classUnion_Find(): def__init__(self, n: int): """Initialize a list: Nodes as index and root as value, count: the number of disjoint set, """ self.len = n self.uf = [i for i inrange(self.len)] self.count = n self.size = [1for i inrange(self.len)]
deffind(self, p:int)->int: """find the root of p""" while self.uf[p] != p: p = self.uf[p] return p
defis_connected(self, p: int, q: int)->bool: """decide if p and q are in the same disjoint set """ return self.find(p) == self.find(q)
# weighted-quick-union classUnion_Find(): def__init__(self, n: int): """Initialize a list: Nodes as index and root as value, count: the number of disjoint set, """ self.len = n self.uf = [i for i inrange(self.len)] self.count = n self.size = [1for i inrange(self.len)]
deffind(self, p:int)->int: """find the root of p""" res = p while self.uf[res] != res: res = self.uf[res] while self.uf[p] != p: p, self.uf[p] = self.uf[p], res return res
defis_connected(self, p: int, q: int)->bool: """decide if p and q are in the same disjoint set """ return self.find(p) == self.find(q)
classSolution: deffindCircleNum(self, isConnected: List[List[int]]) -> int: n = len(isConnected) uf = Union_Find(n) for i inrange(n-1): for j inrange(i+1, n): if isConnected[i][j]: uf.union(i, j) return uf.count
classSolution: defswimInWater(self, grid: List[List[int]]) -> int: n = len(grid) uf = Union_Find(n*n) defheight_t(t): for i inrange(n): for j inrange(n): if grid[i][j] == t: return i, j j += 1 i += 1 for t inrange(1, n*n): i, j = height_t(t) if i-1 >= 0and grid[i-1][j] <= t: uf.union(grid[i][j], grid[i-1][j]) if i+1 < n and grid[i+1][j] <= t: uf.union(grid[i][j], grid[i+1][j]) if j-1 >= 0and grid[i][j-1] <= t: uf.union(grid[i][j], grid[i][j-1]) if j+1 < n and grid[i][j+1] <= t: uf.union(grid[i][j], grid[i][j+1]) if uf.is_connected(grid[0][0], grid[n-1][n-1]): return t return t
for equation in equations: alpha_set.add(equation[0]) alpha_set.add(equation[3])
n = 0 for i in alpha_set: alpha_dict[i] = n n += 1
uf = Union_Find(n)
equations.sort(key=lambda x: x[1], reverse=True)
for equation in equations: if equation[1] == '=': uf.union(alpha_dict[equation[0]], alpha_dict[equation[3]]) elif uf.is_connected(alpha_dict[equation[0]], alpha_dict[equation[3]]): returnFalse returnTrue
classSolution: deffindLengthOfLCIS(self, nums: List[int]) -> int: n = len(nums) if n == 0: return0 uf = Union_Find(n) for i inrange(n-1): if nums[i] < nums[i+1]: uf.union(i, i+1) ## returnmax(uf.size)
classSolution: defmaxNumEdgesToRemove(self, n: int, edges: List[List[int]]) -> int: uf_Alice = Union_Find(n) uf_Bob = Union_Find(n) res = 0 edge1, edge2, edge3 = [], [], [] for edge in edges: if edge[0] == 1: edge1.append(edge[1:]) elif edge[0] == 2: edge2.append(edge[1:]) else: edge3.append(edge[1:])
#先连接公共边 for i, j in edge3: if uf_Alice.is_connected(i-1, j-1): res += 1 else: uf_Alice.union(i-1, j-1) uf_Bob.union(i-1, j-1) #再连接Alice for i, j in edge1: if uf_Alice.is_connected(i-1, j-1): res += 1 else: uf_Alice.union(i-1, j-1) #再连接Bob for i, j in edge2: if uf_Bob.is_connected(i-1, j-1): res += 1 else: uf_Bob.union(i-1, j-1)
if uf_Alice.count == 1and uf_Bob.count == 1: return res else: return -1
classSolution: defminimumEffortPath(self, heights: List[List[int]]) -> int: row, col = len(heights), len(heights[0]) if row == 1and col == 1: return0 weighted_edges = [] n = row*col #通过往左往上构造边 for i inrange(row): for j inrange(col): index = i * col + j if i > 0: weighted_edges.append((index - col, index, abs(heights[i][j] - heights[i-1][j]))) if j > 0: weighted_edges.append((index - 1, index, abs(heights[i][j] - heights[i][j-1]))) weighted_edges.sort(key=lambda x: x[2]) uf = Union_Find(n) for i, j, w in weighted_edges: uf.union(i, j) if uf.is_connected(0, row*col-1): return w