def areSentencesSimilarTwo(self, words1: List[str], words2: List[str], pairs: List[List[str]]) -> bool: global_incr = 0 def getWordIdx(word: str, dictionary: Dict[str, int], create: bool = False) -> int: nonlocal global_incr if word in dictionary: return dictionary[word] elif create: dictionary[word] = global_incr global_incr += 1 return dictionary[word] return -1 if len(words1) != len(words2): return False N = len(pairs) * 2 uf = UF(N) # use a word-to-index map to map all words to UnionFind's int data structure (starting from 0!) hashmap = dict() # build union-find forest from all similar pairs, similar words will compose a cycle inside for edge in pairs: u = getWordIdx(edge[0], hashmap, True) v = getWordIdx(edge[1], hashmap, True) uf.union(u, v) # compare each word in words1 and words2 to see whether they are similar for i, w1 in enumerate(words1): w2 = words2[i] if w1 == w2: continue u, v = getWordIdx(w1, hashmap), getWordIdx(w2, hashmap) if u < 0 or v < 0: return False if uf.find(u) != uf.find(v): return False return True
def findCircleNum(self, M: List[List[int]]) -> int: N = len(M) uf = UF(N) for i in range(N): for j in range(i + 1, N): if M[i][j]: # merge as many direct friends as possible into clusters uf.union(i, j) # how many root nodes after unions clusters = set() for i in range(N): clusters.add(uf.find(i)) size = len(clusters) print(size) return size