当前位置: 首页 > article >正文

图-岛屿-dfs

前言

参考:https://mp.weixin.qq.com/s/IZQkb-M27dt-AZ1VICThOw
岛屿系列问题可以用 DFS/BFS 算法或者 Union-Find 并查集算法 来解决。

用 DFS 算法解决岛屿题目是最常见的,每次遇到一个岛屿中的陆地,就用 DFS 算法吧这个岛屿「淹掉」。

如何使用 DFS 算法遍历二维数组?你把二维数组中的每个格子看做「图」中的一个节点,这个节点和周围的四个节点连通,这样二维矩阵就被抽象成了一幅网状的「图」。

为什么每次遇到岛屿,都要用 DFS 算法把岛屿「淹了」呢?主要是为了省事,避免维护 visited 数组。

图算法遍历基础 说了,遍历图是需要 visited 数组记录遍历过的节点防止走回头路。

因为 dfs 函数遍历到值为 0 的位置会直接返回,所以只要把经过的位置都设置为 0,就可以起到不走回头路的作用。

PS:这类 DFS 算法还有个别名叫做 FloodFill 算法,现在有没有觉得 FloodFill 这个名字还挺贴切的~

200. 岛屿数量

https://leetcode.cn/problems/number-of-islands/description/?envType=study-plan-v2&envId=top-100-liked
// 详细解析参见:
https://labuladong.online/algo/slug.html?slug=number-of-islands

// 注意:cpp 代码由 chatGPT🤖 根据我的 java 代码翻译。
// 本代码的正确性已通过力扣验证,如有疑问,可以对照 java 代码查看。

class Solution {
public:
    // 主函数,计算岛屿数量
    int numIslands(vector<vector<char>>& grid) {
        int res = 0;
        int m = grid.size(), n = grid[0].size();
        // 遍历 grid
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    // 每发现一个岛屿,岛屿数量加一
                    res++;
                    // 然后使用 DFS 将岛屿淹了
                    dfs(grid, i, j);
                }
            }
        }
        return res;
    }

    // 从 (i, j) 开始,将与之相邻的陆地都变成海水
    void dfs(vector<vector<char>>& grid, int i, int j) {
        int m = grid.size(), n = grid[0].size();
        if (i < 0 || j < 0 || i >= m || j >= n) {
            // 超出索引边界
            return;
        }
        if (grid[i][j] == '0') {
            // 已经是海水了
            return;
        }
        // 将 (i, j) 变成海水
        grid[i][j] = '0';
        // 淹没上下左右的陆地
        dfs(grid, i + 1, j);
        dfs(grid, i, j + 1);
        dfs(grid, i - 1, j);
        dfs(grid, i, j - 1);
    }
};

使用常规visit数组标识是否问过:

class Solution {
private:
public:
    int numIslands(vector<vector<char>>& grid)
    {
        int m = grid.size(), n = grid[0].size();
        int islands = 0;
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1' && !visited[i][j]) {
                    dfs(grid, i, j, visited);
                    islands++;
                }
            }
        }
        return islands;
    }

    void dfs(const vector<vector<char>>& grid, int i, int j, vector<vector<bool>>& visited) 
    {
        int m = grid.size(), n = grid[0].size();
        if (i < 0 || j < 0 || i >= m || j >= n) {
            return;
        }

        if (visited[i][j] || grid[i][j] == '0') {
            return;
        }

        visited[i][j] = true;
        dfs(grid, i + 1, j, visited);
        dfs(grid, i - 1, j, visited);
        dfs(grid, i, j + 1, visited);
        dfs(grid, i, j - 1, visited);
    }
};

http://www.kler.cn/a/504629.html

相关文章:

  • 【Unity3D】【已解决】TextMeshPro无法显示中文的解决方法
  • 12 USART串口通讯
  • 如何使用 Excel 进行多元回归分析?
  • 【端云一体化】云函数的使用
  • 【AI游戏】基于OpenAI打造自动生成剧情的 Python 游戏
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • 什么是docker?关于docker容器的全面详细介绍
  • Spring MVC流程一张图理解
  • 获取文章列表功能
  • LeetCode热题100-有效的括号【JavaScript讲解】
  • 常见好用的PHP CMS开源系统有哪些?
  • javaEE-网络原理-IP协议
  • 微信小程序实现个人中心页面
  • Ubuntu磁盘空间不足或配置错误时,如何操作扩容?
  • Starrocks 存算分离 VS Trino 性能测试
  • 银河麒麟V10安装第二个nginx服务
  • Unity 自定义批量打包工具
  • TCP、UDP的区别及使用场景
  • 装备制造业:建立项目“四算”管理:以合同为源头,以项目为手段实现合同的测算、预算、核算与决算的管控体系
  • [云讷科技] 用于软件验证的仿真环境
  • flow-matching based TTS : VoiceBox, E2-TTS, maskGCT
  • 数据结构与算法之栈: LeetCode 1047. 删除字符串中的所有相邻重复项 (Ts版)
  • JVM 核心知识点总结
  • springboot使用阿里oss实现文件上传
  • 如何优化Elasticsearch大文档查询?
  • haproxy+httpd网站架构,实现负载均衡实验笔记