示例#1
0
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid or not len(grid) or not len(grid[0]):
            return 0
        R = len(grid)
        C = len(grid[0])
        cnt = 0
        for i in range(R):
            for j in range(C):
                if grid[i][j] == '1':
                    cnt += 1
        # Special: uf.count (number of '1's is not equal to len(self.parents) in this case
        uf = UF(R * C, cnt)

        def getFlatIdx(i, j):
            return C * i + j

        directions = [[1, 0], [0, 1]]

        for i in range(R):
            for j in range(C):
                if grid[i][j] == '1':
                    for d in directions:
                        ii, jj = i + d[0], j + d[1]
                        if ii < R and jj < C and grid[ii][jj] == '1':
                            u, v = getFlatIdx(i, j), getFlatIdx(ii, jj)
                            # print((i,j), (ii,jj), u, v)
                            uf.union(u, v)
                            # print(uf.count)
        return uf.count
示例#2
0
    def numIslands2(self, m: int, n: int, positions: List[List[int]]) -> List[int]:
        grid = [[0 for _ in range(n)] for _ in range(m)]
        uf = UF(m * n, 0)

        def getFlatIdx(i, j):
            return n * i + j

        directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
        res = []
        input_set = set()
        for pos in positions:
            # edge case - dedupe
            x, y = pos[0], pos[1]
            if (x,y) in input_set:
                res.append(uf.count)
                continue
            input_set.add((x,y))
            grid[x][y] = 1
            uf.count += 1
            for direction in directions:
                u = x + direction[0]
                v = y + direction[1]
                if 0 <= u < m and 0 <= v < n and grid[u][v] == 1:
                    uf.union(getFlatIdx(x, y), getFlatIdx(u, v))
            res.append(uf.count)
        print(res)
        return res
示例#3
0
 def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
     N = len(edges)
     uf = UF(N)
     for edge in edges:
         if not uf.union(edge[0] - 1, edge[1] - 1):
             print(edge)
             return edge
     return []
示例#4
0
 def minSwapsCouples(self, row: List[int]) -> int:
     N = len(row) // 2  # floor division
     uf = UF(N)
     for i in range(N):
         a, b = row[2 * i], row[2 * i + 1]
         uf.union(a // 2, b // 2)
     res = N - uf.count
     print(res)
     return res
示例#5
0
    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
示例#6
0
 def longestConsecutive(self, nums: List[int]) -> int:
     N = len(nums)
     uf = UF(N)
     hashmap: Dict[int, int] = dict()
     directions = [1, -1]
     for i, num in enumerate(nums):
         # edge case - dedupe duplicate elements
         if num in hashmap:
             continue
         hashmap[num] = i
         # if consecutive number is also in hashmap, union as an edge
         for direction in directions:
             if num + direction in hashmap:
                 uf.union(i, hashmap[num + direction])
     res = uf.maxUnion()
     print(res)
     return res
示例#7
0
    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
示例#8
0
 def __init__(self, n: int):
     UF.__init__(self, n)
     self.parents = [-1] * n
     self.weights = [1.0] * n