题目描述:有一个 m x n 的二元网格,其中 1 表示砖块,0 表示空白。砖块 稳定(不会掉落)的前提是:
一块砖直接连接到网格的顶部,或者
至少有一块相邻(4 个方向之一)砖块 稳定 不会掉落时
给你一个数组 hits ,这是需要依次消除砖块的位置。每当消除 hits[i] = (rowi, coli) 位置上的砖块时,对应位置的砖块(若存在)会消失,然后其他的砖块可能因为这一消除操作而掉落。一旦砖块掉落,它会立即从网格中消失(即,它不会落在其他稳定的砖块上)。
返回一个数组 result ,其中 result[i] 表示第 i 次消除操作对应掉落的砖块数目。
注意,消除可能指向是没有砖块的空白位置,如果发生这种情况,则没有砖块掉落。
解题思路:并查集+逆序思考,变为添加砖块进行合并的操作,对每个新添加的砖块只需要考虑他的上下左右四个方位
class UnionFind(object):
def __init__(self, n):
self.father = list(range(n))
self.size = [1] * n
def find(self, x):
root = x
while(root != self.father[root]):
root = self.father[root]
while(x != root):
origin_r = self.father[x]
self.father[x] = root
x = origin_r
return root
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x != root_y:
self.father[root_x] = root_y
self.size[root_y] += self.size[root_x]
def getsize(self, x):
root_x = self.find(x)
return self.size[root_x]
class Solution:
def hitBricks(self, grid: List[List[int]], hits: List[List[int]]) -> List[int]:
m = len(grid)
n = len(grid[0])
copy = deepcopy(grid)
l = len(hits)
for i in range(l):
x, y = hits[i]
copy[x][y] = 0
size = n * m
uf = UnionFind(size+1)
for i in range(n):
if copy[0][i]:
uf.union(i, size)
for i in range(1, m):
for j in range(n):
if copy[i][j] == 1:
if copy[i-1][j]:
uf.union((i-1)*n+j, i*n+j)
if j > 0 and copy[i][j-1]:
uf.union(i*n+j-1, i*n+j)
res = [0] * l
direc = [-1, 0, 1, 0, -1]
for i in range(l-1, -1, -1):
x, y = hits[i]
if grid[x][y] == 0:
continue
origin_size = uf.getsize(size)
if x == 0:
uf.union(y, size)
for j in range(4):
newx = x + direc[j]
newy = y + direc[j+1]
if 0 <= newx < m and 0 <= newy < n and copy[newx][newy]:
uf.union(x*n+y, newx*n+newy)
cur_size = uf.getsize(size)
copy[x][y] = 1
res[i] = max(0, cur_size-origin_size-1)
return res