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.
先给出二维矩阵的行列值,之后再给出一系列操作数目,每个操作是在一个位置插入岛屿。和Number of Islands这种先给出全部岛屿布图不一样,这种情景下更适合使用并查集,因为预先给出岛屿分布,还是无法确定操作的数目,需要扫描二维矩阵,判断为1的地方进行操作。反而使用DFS更方便一些。这题每次加入一个一个岛屿相当于新加入一个集合。之后判断这个新加岛屿上下左右是否有岛屿,如果存在的话,进行集合的合并,把当前岛屿加入,并减少岛屿的个数。
# 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
以上操作的最多合并次数为4k次,object k个。所以时间复杂度为O((4k+k)log*k).log*为迭代次数,不超过5,所以时间复杂度为O(k)大小。空间复杂度为两个dict(权重和father),O(k)大小。由于key值是tuple,空间消耗非常大,所以这种解法在lintcode上MLE. 可以每次将二维坐标转化为一维坐标来做键值。