Number of Islands II

union and find

Abstraction:

  • objects
  • Disjoint sets of objects
  • find - are two objects in the same sets?
  • union - replace sets containing two items by their union. simply speaking is to merge two sets

see here

two optimized mechanisms:

  • weighted union-find
    • store the information of the tree's size
    • merge the small tree into the big tree
  • compress the path
    • flatten the tree
    • so that the find() can run very fast
    • make every other node in path point to its grandparent
class Solution(object):
    def numIslands2(self, m, n, positions):
        """
        :type m: int
        :type n: int
        :type positions: List[List[int]]
        :rtype: List[int]
        """
        directions = [(1,0), (-1,0), (0,1), (0,-1)]
        union = Union()
        res = []

        for p in positions:
            union.add((p[0], p[1]))

            for dir in directions:
                tmp = (p[0]+dir[0], p[1]+dir[1])
                if tmp in union.id:
                    union.unite(tmp, (p[0], p[1]))

            res.append(union.cnt)

        return res


class Union(object):
    def __init__(self):
        self.id = {}
        self.weighted = {}
        self.cnt = 0

    def add(self, i):
        self.id[i] = i
        self.weighted[i] = 1
        self.cnt += 1

    def find(self, i):
        while i != self.id[i]:
            self.id[i] = self.id[self.id[i]]     ##### compress the path
            i = self.id[i]
        return i

    def unite(self, i, j):
        rooti = self.find(i)
        rootj = self.find(j)

        if rooti == rootj:
            return

        if self.weighted[rooti] > self.weighted[rootj]:   ###### weighted unite
            self.id[rootj] = rooti
            self.weighted[rooti] += 1
        else:
            self.id[rooti] = rootj
            self.weighted[rootj] += 1

        self.cnt -= 1

results matching ""

    No results matching ""