算法--岛屿数量

算法--岛屿数量


)

题目

描述
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
例如:
输入
[
[1,1,0,0,0],
[0,1,0,1,1],
[0,0,0,1,1],
[0,0,0,0,0],
[0,0,1,1,1]
]
对应的输出为3
(注:存储的01数据其实是字符’0’,‘1’)
示例1
输入:
[[1,1,0,0,0],[0,1,0,1,1],[0,0,0,1,1],[0,0,0,0,0],[0,0,1,1,1]]
复制
返回值:
3
复制
示例2
输入:
[[0]]
复制
返回值:
0
复制
示例3
输入:
[[1,1],[1,1]]
复制
返回值:
1
复制
备注:
01矩阵范围<=200*200

解题答案

java

package net.test.app.liko;

import static org.apache.hadoop.yarn.webapp.hamlet.HamletSpec.Media.print;
import static sun.misc.Version.print;

/**
 * @author dpx
 * @date 2023/8/21 9:57
 * @Version 1.0
 */
public class SolutionDaoYu {
    public static void main(String[] args) {
        char[][] arr1 = {{'1', '1', '0', '0', '0'},
                {'0', '1', '0', '1', '1'},
                {'0', '0', '0', '1', '1'},
                {'0', '0', '0', '0', '0'},
                {'0', '0', '1', '1', '1'}};

        char[][] arr = new char[5][5];

        arr[0] = new char[]{'1', '1', '0', '0', '0'};
        arr[1] = new char[]{'0', '1', '0', '1', '1'};
        arr[2] = new char[]{'0', '0', '0', '1', '1'};
        arr[3] = new char[]{'0', '0', '0', '0', '0'};
        arr[4] = new char[]{'0', '0', '1', '1', '1'};

        System.out.println(SolutionDaoYu.solve(arr));
    }

    public static int solve(char[][] grid) {
        // 边界条件判断
        if (grid == null || grid.length == 0) return 0;
        // 统计孤岛的个数
        int count = 0;
        // 两个for循环遍历每一个格子
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                //只有当前格子是1才开始计算
                if (grid[i][j] == '1') {
                    // 如果当前格子是1, 岛屿的数量加1
                    count++;
                    // 然后通过dfs把当前格子的上下左右4个位置都置为0, 连着的算一个岛屿
                    dfs(grid, i, j);
                }
            }
        }
        // 返回岛屿的数量
        return count;
    }

    // 将矩阵中当前格子以及其它临近的为1的格子都会置为1
    public static void dfs(char[][] grid, int i, int j) {
        // 边界条件判断, 不能越界
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
        // 把当前格子置为0, 然后从他的上下左右四个方向继续遍历
        grid[i][j] = '0';
        dfs(grid, i - 1, j); // 上
        dfs(grid, i + 1, j); // 下
        dfs(grid, i, j - 1); // 左
        dfs(grid, i, j + 1); // 右
    }


}

scala

package net.clickwifi.app.test.liKo

/**
 * @author dpx
 * @date 2023/8/16 11:11
 * @Version 1.0
 *
 */
object SolutionDaoYu {
  /**
   * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
   *
   * 判断岛屿数量
   *
   * @param grid char字符型二维数组
   * @return int整型
   */
  def main(args: Array[String]): Unit = {

    val grid: Array[Array[Char]] = Array(
      Array('1', '1', '0', '0', '0'),
      Array('0', '1', '0', '1', '1'),
      Array('0', '0', '0', '1', '1'),
      Array('0', '0', '0', '0', '0'),
      Array('0', '0', '1', '1', '1')
    )

    println(solve(grid))
  }

  def solve(grid: Array[Array[Char]]): Int = {
    val n = grid.length
    //空矩阵的情况
    if (n == 0) return 0
    val m = grid(0).length
    //记录岛屿数
    var count = 0
    //遍历矩阵
    for (i <- 0 until n) {
      for (j <- 0 until m) {
        //遍历到1的情况
        if (grid(i)(j) == '1') {
          //计数
          count += 1
          //将与这个1相邻的所有1置为0
          dfs(grid, i, j)
        }
      }
    }
    return count
  }

  //深度 优先遍历与i,j相邻的所有1
  def dfs(grid: Array[Array[Char]], i: Int, j: Int): Unit = {
    val n = grid.length
    val m = grid(0).length
    // 置为0
    grid(i)(j) = '0'
    //后续四个方向遍历
    if (i - 1 >= 0 && grid(i - 1)(j) == '1') dfs(grid, i - 1, j)
    if (i + 1 < n && grid(i + 1)(j) == '1') dfs(grid, i + 1, j)
    if (j - 1 >= 0 && grid(i)(j - 1) == '1') dfs(grid, i, j - 1)
    if (j + 1 < m && grid(i)(j + 1) == '1') dfs(grid, i, j + 1)
  }
}

### 岛屿数量问题的算法题解决方案及其实现 #### 问题描述 给定一个二维网格 `grid`,其中 `'1'` 表示陆地,`'0'` 表示水域。目标是计算该网格中的岛屿数量两个相邻的 `'1'` 如果水平或垂直相连,则认为它们属于同一个岛屿--- #### 解决方案概述 此问题可以通过 **深度优先搜索(DFS)** 或 **广度优先搜索(BFS)** 来解决。以下是基于 DFS 的实现方法: 1. 使用一个辅助布尔型二维组 `visit` 记录已访问过的节点位置。 2. 遍历整个网格,当遇到未被访问且值为 `'1'` 的单元格时,启动一次 DFS 搜索。 3. 在每次 DFS 中,标记当前节点及其所有连接的邻居节点为已访问状态。 4. 统计触发 DFS 的次即为岛屿数量。 这种方法的时间复杂度为 O(m×n),其中 m 和 n 分别表示网格的高度和宽度[^1]。 --- #### 完整代码实现 下面是完整的 Go 语言实现代码: ```go package main import ( "fmt" ) // 主函用于调用 numIslands 函并打印结果 func main() { grid := [][]byte{ {'1', '1', '0', '0', '0'}, {'1', '1', '0', '0', '0'}, {'0', '0', '1', '0', '0'}, {'0', '0', '0', '1', '1'}, } fmt.Println(numIslands(grid)) // 输出应为 3 } // numIslands 是核心逻辑函,返回岛屿数量 func numIslands(grid [][]byte) (res int) { m, n := len(grid), len(grid[0]) // 创建指定长度的二维切作为 visited 组 visit := make([][]bool, m) for i := range visit { visit[i] = make([]bool, n) } // 遍历每个单元格 for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == '1' && !visit[i][j] { DFS(grid, &visit, i, j) // 启动 DFS 并增加岛屿器 res++ } } } return res } // DFS 进行深度优先搜索 func DFS(grid [][]byte, visit *[][]bool, x, y int) { (*visit)[x][y] = true // 将当前位置标记为已访问 // 判断上方 if x-1 >= 0 && !(*visit)[x-1][y] && grid[x-1][y] == '1' { DFS(grid, visit, x-1, y) } // 判断右侧 if y+1 < len(grid[0]) && !(*visit)[x][y+1] && grid[x][y+1] == '1' { DFS(grid, visit, x, y+1) } // 判断下方 if x+1 < len(grid) && !(*visit)[x+1][y] && grid[x+1][y] == '1' { DFS(grid, visit, x+1, y) } // 判断左侧 if y-1 >= 0 && !(*visit)[x][y-1] && grid[x][y-1] == '1' { DFS(grid, visit, x, y-1) } } ``` 上述代码实现了通过 DFS 方法统计岛屿数量的功能,并提供了一个测试样例验证其正确性[^4]。 --- #### 关键点解析 1. **初始化访问记录组** 构建与输入网格大小相同的布尔组 `visit`,用来跟踪哪些单元格已经被处理过,从而避免重复访问同一块土地[^1]。 2. **边界条件检查** 在执行 DFS 调用前需确认索引不会越界以及目标单元格尚未被访问过,这是防止程序崩溃的关键部分[^2]。 3. **递归终止条件** 当某个方向上的邻近单元格不符合继续探索的要求时(比如超出范围或者已经是海水),则停止对该路径进一步深入探查[^4]。 --- 问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值