Java 中查找岛屿的数量

17 Mar 2025 | 6 分钟阅读

查找岛屿数量问题是标准问题,通常在顶尖公司的编码轮面试中被问到。这个问题基于图论。在图论中,我们查找连通分量的数量。在这个问题中,我们也需要做同样的事情。因此,在本节中,我们将讨论岛屿问题陈述、算法以及查找岛屿数量的 Java 程序。

问题陈述

在这个问题中,岛屿只不过是布尔一维、二维或多维 (n 维) 数组中相连的“1”的集合。在这个问题中,我们需要查找布尔矩阵中岛屿(“1”的集合)的数量。“1”表示陆地。

陈述可以重写如下。

给定一个布尔二维矩阵,其中“1”表示陆地,“0”表示水。在这个矩阵中,我们需要计算岛屿的数量。岛屿是环绕着水并且由水平或垂直相邻陆地连接而形成的区域。假设网格的所有四个边缘都环绕着水。下图描绘了这一点。

Find Number of Island in Java

在上图中,用绿色突出显示的方块(“1”)表示陆地,用黄色突出显示的方块(“0”)表示水。上述矩阵有五个岛屿。

上述问题与无向图中的连通分量有关。因此,我们首先将理解什么是连通分量。

连通分量

连通分量是指图中的每对节点都可以通过路径相互连接,并且不与子图之外的任何其他顶点连接。例如,考虑以下图。

Find Number of Island in Java

示例

考虑以下矩阵。

Find Number of Island in Java

在上图中,只有一个相连的“1”的集合。因此,它表示只有一个岛屿。

问题解决方案

这个问题有许多解决方案。它可以是使用 DFS 或 BFS 来解决。在本节中,我们将使用递归和非递归的 DFS 方法来解决这个问题。

使用深度优先搜索 (DFS)

在这种方法中,我们将逐一遍历矩阵中的所有陆地(“1”)。如果我们发现任何未遍历或尚未访问过的陆地,这意味着我们找到了一个新的岛屿。一旦我们访问了一个岛屿,我们将岛屿数量加 1。使用 DFS 或 BFS,我们将所有相连的陆地标记为已访问。

算法

  • 定义一个布尔数组,并将所有值设置为 false。
  • 定义一个变量ans并将其初始化为 0。我们将在此变量中存储最终答案。
  • 遍历网格的每个元素。
  • 检查它是否是陆地(“1”),如果不是,则将变量ans加一。
  • 之后,为此元素启动 DFS 或 BFS 遍历。

查找岛屿数量的 Java 程序

递归方法

在以下 Java 程序中,我们维护了一个名为visited的数组。它跟踪我们已经访问过的陆地。定义并初始化一个变量answer,它存储岛屿的数量。

让我们在 Java 程序中实现上述方法。

NumberOfIslands.java

输出

Number of Islands: 3

使用非递归方法

NumberOfIslands.java

输出

Number of Islands: 5

复杂度

对于上述问题,时间复杂度为O(n*m),因为我们至少访问了网格的每个元素一次。其中,n 是行数,m 是列数。

上述方法空间复杂度为O(n*m),因为我们使用了一个二维数组来存储陆地是否已被访问。