题目描述(中等难度)

一个二维数组,把 看做陆地,把 0 看做大海,陆地相连组成一个岛屿。把数组以外的区域也看做是大海,问总共有多少个岛屿。

解法一

想法很简单,我们只需要遍历二维数组,然后遇到 1 的时候,把当前的 1 以及它周围的所有 1 都标记成一个字符,这里直接标记成 2。然后记录遇到了几次 1,就代表有几个岛屿。看下边的例子。

还有一个问题就是怎么标记与当前 相邻的 1。也很直接,我们直接把和当前 1 连通的位置看做一个图,然后做一个遍历即可。可以直接用递归写一个 DFS,即深度优先遍历。

当然做遍历的话,我们也可以采用 BFS,广度优先遍历。图的广度优先遍历和二叉树的 类似,只需要借助一个队列即可。

和上边的区别不大,改一下标记函数即可。

此外入队列的时候,我们把二维坐标转为了一维,就省去了再创建一个类表示坐标。

解法二 并查集

一开始看到这道题,我其实想到的是并查集,然后想了想感觉有些复杂,复杂度可能会高一些,就换了下思路想到了解法一。逛了一下 Discuss 发现也有人用并查集实现了,那这里也再总结下。

看下维基百科对 并查集 的定义。

网上很多讲并查集的文章了,这里推荐 ,大家可以先去看一下。

知道了并查集,下边就很好解决了,因为你会发现,我们做的就是分类的问题,把相邻的 1 都分成一类。

首先我们把每个节点各作为一类,用它的行数和列数生成一个 标识该类。

遍历每个为 1 的节点,将它的右边和下边的 1 和当前节点合并(这里算作一个优化,不需要像解法一那样上下左右)。每进行一次合并,我们就将 nums1

最后返回 即可。

解法一标记的思想前边的题目也遇到过好多次了,解法二的话算作一个通用的解法,当发现题目是分类相关的,可以考虑并查集。

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 查看详情