803. 打砖块

题目描述:有一个 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
            
        
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值