Number of Islands II

Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y means that you can change the grid matrix[A[i].x][A[i].y] from sea to island. Return how many island are there in the matrix after each operator.

Value is given to the ranks of two-dimensional matrix, and then, after a series of given number of operations, each of the island is inserted in one position. Number of Islands and this prior analysis of all island layout is not the same, this scenario is more suitable for use disjoint-set, since the island distribution given in advance, or the number of operations can not be determined, need to scan two-dimensional matrix, it is determined 1 place to operate. Instead, use DFS easier. This is a question each addition of an island equivalent of adding a new collection. After the vertical and horizontal islands determined whether this new island plus, if present, are combined set, the current islands was added, and reduce the number of islands.

# Definition for a point.
# class Point:
#     def __init__(self, a=0, b=0):
#         self.x = a
#         self.y = b

class Solution:
    # @param {int} n an integer
    # @param {int} m an integer
    # @param {Pint[]} operators an array of point
    # @return {int[]} an integer array
    def numIslands2(self, n, m, operators):
        if not m or not n or not operators:
            return []
        UF = UnionFind()
        res = []
        for p  in  map(lambda a: (a.x, a.y), operators):
            UF.add(p)
            for dx in (1, 0), (0, 1), (-1, 0), (0, -1):
                q =  (dx[0] + p[0], dx[1]+p[1])
                if q in UF.id:
                    UF.union(p,q)
            res += [UF.count]
        return res
                    
class UnionFind(object):
    def __init__(self):
        self.id = {} #object
        self.sz = {} #object'weight, size here.
        self.count = 0
        
    def add(self, p):
        self.id[p] = p
        self.sz[p] = 1
        self.count += 1
        
    def find(self, i):
        while i!= self.id[i]:
            self.id[i] = self.id[self.id[i]] #路径压缩
            i = self.id[i]
        return i

    def union(self, p, q):
        i = self.find(p)
        j = self.find(q)
        if i == j:
            return
        if self.sz[i] > self.sz[j]: #union is only operated on heads按秩合并
            i, j = j, i
        self.id[i] = j
        self.sz[i] += self.sz[j]
        self.count -= 1

The combined maximum number of times the above operation is 4k, object k a. Therefore, the time complexity is O ((4k + k) log * k) .log * is the iteration number, no more than 5, the time complexity is O (k) size. Spatial complexity is two dict (weights and father), O (k) size. Since the key tuple values, space consumption is very large, so this solution on the MLE lintcode. Each time the two-dimensional coordinates may be converted to one-dimensional coordinate keys do. 

Leetcode version Solution: two-dimensional coordinates into a one-dimensional digital expression, we must take note of the number of columns is not the number of rows !!

class Solution(object):
    def numIslands2(self, m, n, positions):
        """
        :type m: int
        :type n: int
        :type positions: List[List[int]]
        :rtype: List[int]
        """
        #union find method
        #union find init function, find function, union function,add function the basic architecture is hashmap.
        #extra space-saving method, turn the 2D coordinates into 1D, multiply the number of column not row
        res = []
        delta = [1,0,-1,0,1]
        UF = UnionFind()
        for a in positions:
            UF.add(a[0]*n + a[1])
            for i in xrange(4):
                x = a[0] + delta[i]
                y = a[1] + delta[i+1]
                p = x*n+y
                if 0 <= x < m and 0 <= y < n and p in  UF.root:
                    UF.union(a[0]*n + a[1], p)
            res.append(UF.cnt)
        return res
class UnionFind(object):
    def __init__(self):
        self.root = {}
        self.sz = {}
        self.cnt = 0
    def add(self, x):
        self.root[x] = x
        self.sz[x] = 1
        self.cnt += 1
    def find(self, x): #find the root of a node
        while x!= self.root[x]:
            self.root[x] = self.root[self.root[x]]
            x = self.root[x]
        return x
    def union(self, x, y): #attention, just union the big brother, link smaller union to the larger one
        i = self.find(x)
        j = self.find(y)
        if i != j: #not in the same union
            if self.sz[i] > self.sz[j]:
                self.root[j] = i
                self.sz[i] += self.sz[j]
            else:
                self.root[i] = j
                self.sz[j] += self.sz[i]
            self.cnt -= 1
            
        

 

Reproduced in: https: //www.cnblogs.com/sherylwang/p/5576007.html

Guess you like

Origin blog.csdn.net/weixin_34357887/article/details/94526070