题目描述
这是 LeetCode 上的 827. 最大人工岛 ,难度为 困难。
Tag : 「并查集」、「枚举」
给你一个大小为 n x n
二进制矩阵 grid
。最多 只能将一格 0
变成 1
。
返回执行此操作后,grid
中最大的岛屿面积是多少?
岛屿 由一组上、下、左、右四个方向相连的 1
形成。
示例 1:
示例 2:
示例 3:
提示:
-
grid[i][j]
为0
或1
并查集 + 枚举
为了方便,我们令 grid
为 g
。
根据题意,容易想到通过「并查集」来维护所有连通块大小,再通过「枚举」来找最优翻转点。
具体的,我们可以先使用「并查集」维护所有 的块连通性,并在维护连通性的过程中,使用 sz[idx]
记录下每个连通块的大小(注意:只有连通块根编号,sz[idx]
才有意义,即只有 sz[find(x)]
才有意义)。
随后我们再次遍历 g
,根据原始的
- 若,该位置不会作为翻转点,但真实最大面积未必是由翻转后所导致的(可能取自原有的连通块),因此我们需要将参与比较,其中
root
为 - 若,该位置可作为翻转点,我们可以统计其四联通位置对应的连通块大小总和
tot
(注意若四联通方向有相同连通块,只统计一次),那么
最后对所有连通块大小取最大值即是答案。
一些细节:为了方便,我们令点 的编号从 开始; 同时由于我们本身就要用
sz
数组,因此我们可以随手把并查集的「按秩合并」也加上。体现在 union
操作时,我们总是将小的连通块合并到大的连通块上,从而确保我们并查集单次操作即使在最坏情况下复杂度仍为 (可看作常数)。需要注意只有同时应用「路径压缩」和「按秩合并」,并查集操作复杂度才为 。
Java 代码:
TypeScript 代码:
Python 代码:
- 时间复杂度:
- 空间复杂度:
最后
这是我们「刷穿 LeetCode」系列文章的第 No.827
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour… 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。