LeetCode刷题之HOT100之岛屿数量

2024 6/27 酷暑难耐,天气热了,似乎更容易午睡了。上午上了cnn最后一节课。睡一觉买一杯蜜雪冰城,坐在舒适的实验室敲击键盘,做题!

1、题目描述

在这里插入图片描述

2、逻辑分析

是的,又是直奔题解的一天哈!题解给出三种求解方案:深度优先搜索、广度优先搜索以及并查集。我们只看DFS就可以啦。
算法思想主要是利用了深度优先搜索(DFS)来遍历二维网格,并找出所有的“岛屿”(由 ‘1’ 组成的连续区域)。算法的基本步骤如下:
初始化:
定义一个二维字符数组 grid,其中 ‘1’ 表示陆地(或岛屿的一部分),‘0’ 表示水域。
初始化一个计数器 num_islands0,用于记录岛屿的数量。
遍历网格:
使用两个嵌套的循环遍历整个网格 grid
在遍历过程中,如果当前位置是 ‘1’(即陆地),则表示找到了一个新的岛屿。
深度优先搜索(DFS):
当找到一个新的岛屿(即 ‘1’)时,调用 dfs 函数进行深度优先搜索。
dfs 函数会首先将当前位置的陆地标记为水域(即改为 ‘0’),以避免重复访问。
然后,它会递归地调用自身,搜索当前位置的上、下、左、右四个方向,继续寻找与该岛屿相连的其他陆地。
递归调用会持续进行,直到所有与该岛屿相连的陆地都被标记为水域。
计数:
在每次找到一个新的岛屿(即 ‘1’)时,将 num_islands 计数器加 1
由于 dfs 函数会确保一个岛屿的所有陆地都被标记为水域,因此同一个岛屿不会被重复计数。
返回结果:
遍历完整个网格后,返回 num_islands 的值,即岛屿的数量。

3、代码演示

// 深度优先搜索函数,用于标记和遍历一个岛屿的所有陆地  
    void dfs(char[][] grid, int i, int j){
        // 获取网格的行数和列数
        int nr = grid.length, nc = grid[0].length;
        // 如果当前位置超出网格边界或者已经是水域('0'),则直接返回 
        if(i < 0 || j < 0 || i >= nr || j >= nc || 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);

    }

    // 主函数,用于计算岛屿的数量
    public int numIslands(char[][] grid) {
        // 如果网格为空或者没有行,则直接返回0
        if(grid == null || grid.length == 0){
            return 0;
        }

        // 获取网格的行数和列数
        int nr = grid.length, nc = grid[0].length;
        int num_islands = 0;
        // 遍历网格的每一个位置
        for(int i = 0; i < nr; i++){
            for(int j = 0; j < nc; j++){
                // 如果当前位置是陆地('1')
                if(grid[i][j] == '1'){
                    // 岛屿数量加1
                    num_islands++;
                    // 使用深度优先搜索遍历并标记当前岛屿的所有陆地 
                    dfs(grid, i, j);
                }

            }
        }
        // 返回岛屿数量
        return num_islands;
        
    }

4、复杂度分析

  • 时间复杂度:O(MN),其中 M 和 N 分别为行数和列数。
  • 空间复杂度:O(MN),在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 MN。

ok,做完啦,还有广度优先搜索和并查集就不做啦,看看就好!拜拜,又要去上课了。

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值