# union find ## OO + path compression ```python= class UnionFind: def __init__(self): self.group_id_dict = {} # node_id as key; group_id as value. def find(self, node_id): #if node_id not in self.group_id_dict: # self.group_id_dict[node_id] = node_id #group_id = self.group_id_dict[node_id] group_id = self.group_id_dict.setdefault(node_id, node_id) # Path compressio, recursively updating for all nodes on path. # This will flatten the tree. if group_id != node_id: new_group_id = self.find(group_id) self.group_id_dict[node_id] = new_group_id return self.group_id_dict[node_id] def union(self, x, y): #x_group_id = self.find(x) #y_group_id = self.find(y) # #if x_group_id != y_group_id: # self.group_id_dict[x_group_id] = y_group_id self.group_id_dict[self.find(x)] = self.find(y) # Merge the two group by letting the representative of a group be the # representative of the other union_find = UnionFind() for x, y in pairs: union_find.union(x, y) ``` ## the same, OO + path compression ```python= class UnionFind: def __init__(self): # nid: node id # gid: groud id self.nid2gid = {} def find(self, nid): gid = self.nid2gid.setdefault(nid, nid) if gid!=nid: self.nid2gid[nid] = self.find(gid) return self.nid2gid[nid] # same as gid def union(self, nid_1, nid_2): self.nid2gid[self.find(nid_1)] = self.find(nid_2) class Solution: def equationsPossible(self, equations: List[str]) -> bool: uf = UnionFind() inequality = [] for text in equations: if '==' in text: a, b = text.split('==') uf.union(a, b) else: a, b = text.split('!=') inequality.append([a, b]) for a, b in inequality: if uf.find(a) == uf.find(b): return False return True ``` ## nice ref, path compression when find(), union() by rank https://algorithms.tutorialhorizon.com/disjoint-set-union-find-algorithm-union-by-rank-and-path-compression/