【并查集】93 岛屿数量

news2024/11/28 15:52:36

岛屿数量

    • 题解1 DFS(图论经典方法)
    • 题解2 BFS(遍历(DFS展开【顺序不同】))
    • 题解3 并查集(学习理解)

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:
输入:

grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]

输出:1

示例 2:
输入:

grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]

输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 ‘0’ 或 ‘1’

题解1 DFS(图论经典方法)

class Solution {
    int l, r;
public:
    void dfs(vector<vector<char>>& grid, int ro, int co){
        if(co < 0 || co >= r || ro < 0 || ro >= l ||  grid[ro][co] == '0')
            return;
        // 思想:把1附近相连(连通分量)置0
        // 相当于visited(面试时需要确定是否可以修改grid)
        grid[ro][co] = '0';
		
        dfs(grid, ro, co+1);
        dfs(grid, ro+1, co);
        dfs(grid, ro-1, co);
        dfs(grid, ro, co-1);
    } 
    int numIslands(vector<vector<char>>& grid) {
        int ret = 0;
        l = grid.size();
        r = grid[0].size();
        for(int i = 0; i < l; i++){
            for(int j = 0; j < r; j++){
                if(grid[i][j] == '1'){
                    ret += 1;
                    dfs(grid, i, j);
                }
            }
        }
        return ret;
    }
};

在这里插入图片描述

题解2 BFS(遍历(DFS展开【顺序不同】))

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int ret = 0;
        int m = grid.size();
        int n = grid[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == '1'){
                    ret += 1;
                    grid[i][j] = '0';
                    // BFS典型ADT
                    queue<pair<int, int>> nei;
                    nei.push(make_pair(i, j));
                    while(! nei.empty()){
                        auto rc = nei.front();
                        nei.pop();
                        int r = rc.first;
                        int c = rc.second;
                        if(r >= 1 && grid[r-1][c] == '1'){
                            nei.push(make_pair(r-1, c));
                            grid[r-1][c] = '0';
                        }
                        if(r+1 < m && grid[r+1][c] == '1'){
                            nei.push(make_pair(r+1, c));
                            grid[r+1][c] = '0';
                        }
                        if(c >= 1 && grid[r][c-1] == '1'){
                            nei.push(make_pair(r, c-1));
                            grid[r][c-1] = '0';
                        }
                        if(c+1 < n && grid[r][c+1] == '1'){
                            nei.push(make_pair(r, c+1));
                            grid[r][c+1] = '0';
                        }
                    }
                }
            }
        }
        return ret;
    }
};

在这里插入图片描述

题解3 并查集(学习理解)

class UnionFind {
    vector<int> parent;
    vector<int> rank;
    int count;
public:
    UnionFind(vector<vector<char>>& grid) {
        count = 0;
        int m = grid.size();
        int n = grid[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '1') {
                    parent.push_back(i * n + j);
                    ++count;
                }
                else {
                    parent.push_back(-1);
                }
                rank.push_back(0);
            }
        }
    }

    int find(int i) {
        if (parent[i] != i) {
            parent[i] = find(parent[i]);
        }
        return parent[i];
    }

    void unite(int x, int y) {
        int rootx = find(x);
        int rooty = find(y);
        if (rootx != rooty) {
            if (rank[rootx] < rank[rooty]) {
                swap(rootx, rooty);
            }
            parent[rooty] = rootx;
            if (rank[rootx] == rank[rooty]) rank[rootx] += 1;
            --count;
        }
    }

    int getCount() const {
        return count;
    }
};

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int nr = grid.size();
        if (!nr) return 0;
        int nc = grid[0].size();

        UnionFind uf(grid);
        int num_islands = 0;
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    grid[r][c] = '0';
                    if (r - 1 >= 0 && grid[r-1][c] == '1') uf.unite(r * nc + c, (r-1) * nc + c);
                    if (r + 1 < nr && grid[r+1][c] == '1') uf.unite(r * nc + c, (r+1) * nc + c);
                    if (c - 1 >= 0 && grid[r][c-1] == '1') uf.unite(r * nc + c, r * nc + c - 1);
                    if (c + 1 < nc && grid[r][c+1] == '1') uf.unite(r * nc + c, r * nc + c + 1);
                }
            }
        }

        return uf.getCount();
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1166444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TikTok未来展望:数字创新的下一浪潮

随着全球数字时代的蓬勃发展&#xff0c;TikTok已经成为一个巨大的现象&#xff0c;吸引了数以亿计的用户&#xff0c;尤其是年轻一代。这个短视频分享平台已经深刻影响了社交媒体、娱乐和文化。然而&#xff0c;TikTok未来的发展前景如何&#xff1f;本文将探讨TikTok的未来展…

哈希的开放定址法的实现【C++】

哈希的开放定址法的实现【C】 1 概述2 线性探测2.1 插入2.2 查找2.3 删除2.6 完整代码2.5 线性探测的优缺点 3. 二次探测 1 概述 开放定址法也叫闭散列&#xff0c;是解决哈希冲突的一种方法&#xff0c;当发生哈希冲突之后&#xff0c;如果哈希表没有被装满(正常情况哈希表不会…

饥荒联机版 Don‘t Starve Together(WinMac)最新中文学习版

《饥荒联机版》是由Klei自主开发的开放世界冒险游戏。在这个游戏中&#xff0c;玩家将扮演各种各样的人物&#xff0c;这些人物不幸来到了一个神秘的异世界。在旅行中&#xff0c;玩家会邂逅性格各异、能力独特的同伴们&#xff0c;并和他们一起生存下去并征服异世界。游戏中的…

每日一题 117. 填充每个节点的下一个右侧节点指针 II (中等,树)

BFS&#xff0c;一层层去搜索整棵树&#xff0c;然后建立next关系即可&#xff0c;下面给出的代码的空间复杂度是O(n)的O(1) 的做法&#xff0c;当构建完上一层的next关系后&#xff0c;我们就可以像链表一样从左到右访问上一层的节点&#xff0c;显然在访问的过程中&#xff0…

N-132基于springboot,vue人事管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本项…

自定义类型结构体(下)

目录 结构体传参结构体实现位段什么是位段位段的内存分配位段的跨平台问题总结&#xff1a; 位段的应用位段使用的注意事项** 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1f978;&a…

DataCastle企业风险算法赛实战(进阶难度)

目录 一、数据读取及分析 1、数据读取 2、数据分析 二、数据挖掘 三、模型构建及评估 四、划重点 推荐相关文章 去年在DataCastle上参加了华录杯算法赛&#xff0c;初赛前10、进复赛就没打了。相比于之前文章 kaggle风控建模实战&#xff08;文末附链接&#xff09;&…

智慧财务的未来

信息化时代&#xff0c;财务管理不再局限于传统的手工操作&#xff0c;而是借助RPA技术实现了自动化、智能化的转型。智慧财务作为财务管理的一种新模式&#xff0c;将为企业提供更加高效、便捷的服务&#xff0c;使企业能够更好地适应市场需求的变化&#xff0c;在瞬息万变的市…

批量删除文件名中的某些文字

怎么批量删除文件名中的某些文字&#xff1f;在整理电脑文件的时候&#xff0c;我们经常需要处理大量文件的重命名工作。当你的文件名称包含不必要或重复的字符时&#xff0c;可以进行批量删除&#xff0c;以使文件名称更简洁、清晰&#xff0c;提高可读性和识别性。例如&#…

【蓝桥杯软件赛 零基础备赛20周】第2周——常考知识点+判题

文章目录 0. 第1周答疑1. 常考知识点2. 蓝桥杯怎么判题2.1 判题系统如何判题2.2 测试数据和得分的关系2.3 自己做测试数据 3. 备赛计划4. 本周刷题 0. 第1周答疑 问题1&#xff1a;蓝桥杯怎么报名&#xff0c;什么时候报名&#xff1f; 答&#xff1a;集体报名或个人报名。大…

【word技巧】ABCD选项如何对齐?

使用word文件制作试卷&#xff0c;如何将ABCD选项全部设置对齐&#xff1f;除了一直按空格或者Tab键以外&#xff0c;还有其他方法吗&#xff1f;今天分享如何将ABCD选项对齐。 首先&#xff0c;我们打开【替换和查找】&#xff0c;在查找内容输入空格&#xff0c;然后点击全部…

利用关键字批量整理文件:用关键字轻松移动多个文件到指定文件夹

在日常生活和工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;随着时间的推移&#xff0c;电脑中的文件越来越多&#xff0c;而文件的命名可能并不规范&#xff0c;导致查找和整理变得非常困难。因此&#xff0c;我们需要一种高效的文件管理方法&#xff0c;以方便我…

一种用醋酸刻蚀氧化铜的新方法

引言 由于乙酸不会氧化铜表面&#xff0c;因此乙酸常用于去除氧化铜而不侵蚀铜膜。乙酸还具有低表面张力&#xff0c;易于从表面移除。因此&#xff0c;不需要去离子(DI)水冲洗来移除残留的乙酸&#xff0c;可以防止水冲洗导致的铜再氧化。 英思特研究了在低温下用乙酸去除氧…

SSE加速随笔

Intel Intrinsics Guide 搞懂SSE 寄存器与指令数据细节 SSE指令集推出时&#xff0c;Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器&#xff0c;称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行&#xff0c;并可以与MMX整数运算或x87浮点运…

01、SpringBoot + MyBaits-Plus 集成微信支付 -->项目搭建

目录 SpringBoot MyBaits-Plus 集成微信支付 之 项目搭建1、创建boot项目2、引入Swagger作用&#xff1a;2-1、引入依赖2-2、写配置文件进行测试2-3、访问Swagger页面2-4、注解优化显示 3、定义统一结果作用&#xff1a;3-1、引入lombok依赖3-2、写个统一结果的类-->RR类的…

Windows、程序员必装的工具

一、Typora 啥也不说了直接上图 Markdown语法 Typora免费版 提取码&#xff1a;av01 二维码&#xff1a; 1&#xff09;页面展示 2&#xff09;主题 3&#xff09;偏好设置 4&#xff09;Markdown语法设置偏好 5&#xff09;编辑器 6&#xff09;系统 二、Snipaste Snipaste…

Java反射详解:入门+使用+原理+应用场景

反射非常强大和有用&#xff0c;现在市面上绝大部分框架(spring、mybatis、rocketmq等等)中都有反射的影子&#xff0c;反射机制在框架设计中占有举足轻重的作用。 所以&#xff0c;在你Java进阶的道路上&#xff0c;你需要掌握好反射。 怎么才能学好反射&#xff0c;我们需要…

STM32CubeIDE安装中文语言包

软件包地址&#xff1a;https://archive.eclipse.org/technology/babel/update-site/R0.16.1/2018-12/ 打开IDE&#xff1a;Help--->Install New Software--->Add Locations&#xff1a;输入软件包地址 等待搜索结束&#xff1a;选择中文语言包&#xff0c;单击next进行安…

QQ邮箱发送验证码源码/API+HTML源码/支持API接口、自定义地址和内容/简单易用

源码简介&#xff1a; 一款支持API接口、自定义QQ邮箱地址、自定义邮箱标题和内容的源码。 近来我正在开发一款新的软件&#xff0c;但在注册环节中遇到了一个问题&#xff1a;需要使用QQ邮箱验证码。因此&#xff0c;我积极寻找相关的API接口或开发文档&#xff0c;但遗憾的…

学习小结,学而时习之,坚持学习之,温顾学习之

学习python一个多月了&#xff0c;之前也有接触过&#xff0c;还花了不少钱报班&#xff0c;看了看入门的头两节课&#xff0c;就止步了。每一种编程语言的入门感觉都差不多&#xff0c;学到现在&#xff0c;我对python的基本数据类型还是没掌握好啊&#xff0c;每次列表字典怎…