问题
leetcode-200岛屿数量
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例1:
输入:
11110
11010
11000
00000
输出: 1示例 2:
输入:
11000
11000
00100
00011
输出: 3思路
我们把题目改变一下帮助我们理解。
- 有一种超级病毒,能在特定区域传播,这里我们用1代表可感染区域,把2代表已感染区域,把0代表不会感染的区域。我们把一个连在一起的感染区域称作一个感染区。
- 问:现在病毒来袭,请计算会有几个感染区。
我们遍历矩阵,只要遇到可感染的情况1就进入递归,对其四个方向查找是否可继续感染1,把途径的1标记为已感染2。而后完成整个递归后感染区加1。继续遍历矩阵,直至结束。
下面来看下实际代码。
实现
1 | public static int countIslands(int[][] m){ |
补充:巧用并查集
上面那个解法十分的友好,但在数据量大的时候,那样的解是不可行的。
当数据大的需要用分布式计算的时候常常会把一大块进行分治,这之中有个大问题
当中间区域出现相连的情况,会有重复计算的情况
这时候并查集就可以登场了!!!
- 分布式算出各个感染区:把并且每个感染去独立作为一个集合,其根节点为开始感染的节点,算出总数。
- 合并:找出两两相连的两条边界,遍历其中一条,当有两个相邻节点都是感染时,判断他们是否为同一集合。
- 若不同则总数-1,而后把用并查集union这两个节点。
- 若相同或者均不为感染区,则跳过。
看个图理解一哈:
在分布式的情况下把感染区A、B、C三个集合(根节点可以取第一个感染节点)
- 还有的情况兄弟萌可以自己画一下图(若有两个感染区,两次相邻,我们只会减去1个)
这里仅提供思路,扩展一下并查集的用途。请各位海涵。