LeetCode每日一题,803. Bricks Falling When Hit
先看题目描述
大意就是给定一个只包含 1 和 0 的二维矩阵,其中 1 代表 砖块,0 代表空地,一个砖块是稳定的得满足下面两个条件之一:
- 该砖块直接与二维矩阵顶部相连
- 该砖块相邻的砖块中至少有一个是稳定的
给定 hits 数组代表要敲除的砖块的位置,一个砖块敲除后,可能有一些其他砖块变得不稳定而掉落,让我们返回数组 result,result[i] 代表第 i 个砖块被敲除后,掉落的其他砖块数量
算法和思路
并查集
这题不会,看题解才会的
如何想到并查集
- 当前问题是一个图的连通性问题,砖块和砖块如果在 4 个方向上相邻,表示这两个砖块上有一条边。砖块的相邻关系而产生的连接关系具有传递性;
- 第 0 行的砖块连接着「屋顶」;
- 击碎了一个砖块以后,可能会使得其它与「被击碎砖块」 连接 的砖块不再与顶部相连,然后它们消失;
题目只问结果,没有问具体连接的情况; - 连通的砖块个数是我们所关心的,「并查集」内部可以维护「以当前结点为根结点的子树的结点总数」
如何使用并查集
- 消除一个砖块的效果是:一个连通分量被分成了两个连通分量;
- 并查集的作用是:把两个连通分量合并成一个连通分量
提示我们这个问题需要 反向 思考。即考虑:补上被击碎的砖块以后,有多少个砖块因为这个补上的这个砖块而与屋顶的砖块相连。每一次击碎一个砖块,因击碎砖块而消失的砖块只会越来越少。因此可以按照数组 hits 的顺序 逆序地 把这些砖块依次补上
步骤
- 根据数组 hits,将输入的表格 grid 里的对应位置全部设置为 0 ,这是因为我们要逆序补全出整个初始化的时候二维表格的砖块;
- 从最后一个击碎的砖块开始,计算补上这个被击碎的砖块的时候,有多少个砖块因为这个补上的砖块而与屋顶相连,这个数目就是按照题目中的描述,击碎砖块以后掉落的砖块的数量
实现细节
- 在并查集中设置一个特殊的结点,表示「屋顶」;
- 逆序补回的时候,由于补回,增加的连接到「屋顶」的砖块数应该这样算:res[i] = Math.max(0, current - origin - 1); 因为有可能补回一个砖块前后,连接到「屋顶」的砖块总数没有变化
算法源码
1 | class Solution { |
下面是将并查集作为内部类的写法
1 | class Solution { |