Leetcode200. 岛屿数量

Every day a Leetcode

题目来源:200. 岛屿数量

解法1:深度优先搜索

设目前指针指向一个岛屿中的某一点 (i, j),寻找包括此点的岛屿边界。

从 (i, j) 向此点的上下左右 (i+1,j),(i-1,j),(i,j+1),(i,j-1) 做深度搜索。

终止条件:

  1. (i, j) 越过矩阵边界;
  2. grid[i][j] == 0,代表此分支已越过岛屿边界。

搜索岛屿的同时,执行 grid[i][j] = ‘0’,即将岛屿所有节点删除,以免之后重复搜索相同岛屿。

遍历整个矩阵,当遇到 grid[i][j] == ‘1’ 时,从此点开始做深度优先搜索 dfs,岛屿数 count + 1 且在深度优先搜索中删除此岛屿。

最终返回岛屿数 count 即可。

代码:

/** @lc app=leetcode.cn id=200 lang=cpp** [200] 岛屿数量*/// @lc code=start// 深度优先搜索class Solution
{
private:const int dx[4] = {-1, 0, 1, 0};const int dy[4] = {0, 1, 0, -1};public:int numIslands(vector<vector<char>> &grid){if (grid.empty())return 0;int m = grid.size(), n = m ? grid[0].size() : 0;int islands = 0;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (grid[i][j] == '1'){islands++;dfs(grid, i, j);}return islands;}// 辅函数 - 深度优先搜索void dfs(vector<vector<char>> &grid, int r, int c){if (r < 0 || r >= grid.size() || c < 0 || c >= grid[0].size() || grid[r][c] == '0')return;grid[r][c] = '0';for (int i = 0; i < 4; i++){int x = dx[i], y = dy[i];dfs(grid, r + x, c + y);}}
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(m*n),其中 m 和 n 分别是二维数组 grid 的行数和列数。

空间复杂度:O(m*n),其中 m 和 n 分别是二维数组 grid 的行数和列数。在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 m*n。

解法2:广度优先搜索

同样地,我们也可以使用广度优先搜索代替深度优先搜索。

为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则将其加入队列,开始进行广度优先搜索。在广度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。直到队列为空,搜索结束。

最终岛屿的数量就是我们进行广度优先搜索的次数。

代码:

class Solution
{
public:int numIslands(vector<vector<char>> &grid){if (grid.empty())return 0;int m = grid.size(), n = m ? grid[0].size() : 0;int islands = 0;for (int r = 0; r < m; r++)for (int c = 0; c < n; c++)if (grid[r][c] == '1'){islands++;grid[r][c] = '0';queue<pair<int, int>> neighbors;neighbors.push({r, c});while (!neighbors.empty()){auto rc = neighbors.front();neighbors.pop();int row = rc.first, col = rc.second;if (row - 1 >= 0 && grid[row - 1][col] == '1'){neighbors.push({row - 1, col});grid[row - 1][col] = '0';}if (row + 1 < m && grid[row + 1][col] == '1'){neighbors.push({row + 1, col});grid[row + 1][col] = '0';}if (col - 1 >= 0 && grid[row][col - 1] == '1'){neighbors.push({row, col - 1});grid[row][col - 1] = '0';}if (col + 1 < n && grid[row][col + 1] == '1'){neighbors.push({row, col + 1});grid[row][col + 1] = '0';}}}return islands;}
};

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(m*n),其中 m 和 n 分别是二维数组 grid 的行数和列数。

空间复杂度:O(min⁡(m, n)),其中 m 和 n 分别是二维数组 grid 的行数和列数。在最坏情况下,整个网格均为陆地,队列的大小可以达到 min⁡(m, n)。

解法3:并查集

同样地,我们也可以使用并查集代替搜索。

为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则将其与相邻四个方向上的 1 在并查集中进行合并。

最终岛屿的数量就是并查集中连通分量的数目。

代码:

class UnionFind {
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;}private:vector<int> parent;vector<int> rank;int 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.mzph.cn/news/166279.shtml

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

相关文章

“圆柱-计算公式“技术支持网址

该软件可以计算圆柱的底面圆周长、底面积、侧面积和体积。 您在使用中有遇到任何问题都可以和我们联系。我们会在第一时间回复您。 邮箱地址&#xff1a;elmo30zeongmail.com 谢谢&#xff01;

如何将本地websocket发布至公网并实现远程访问?

本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…

VR云游:让旅游产业插上数字化翅膀,打造地方名片

自多地入冬降温以来&#xff0c;泡温泉成了许多人周末度假的选择&#xff0c;在气温持续走低的趋势下&#xff0c;温泉游也迎来了旺季&#xff1b;但是依旧有些地区温度依旧温暖&#xff0c;例如南京的梧桐美景也吸引了不少游客前去打卡&#xff0c;大家穿着汉服与金黄的树叶合…

【AI考证笔记】NO.1人工智能的基础概念

以下部分内容来自于百度智能云人才认证培训讲义&#xff0c;腾讯等也有人工智能类似的讲义&#xff0c;限时免费&#xff0c;也就是不报考&#xff0c;也能系统学习&#xff0c;课程做的都是不错的。有感兴趣的朋友&#xff0c;可以去检索学习。 本系列是学习笔记&#xff0c;…

6个常用的聚类评价指标

评估聚类结果的有效性&#xff0c;即聚类评估或验证&#xff0c;对于聚类应用程序的成功至关重要。它可以确保聚类算法在数据中识别出有意义的聚类&#xff0c;还可以用来确定哪种聚类算法最适合特定的数据集和任务&#xff0c;并调优这些算法的超参数(例如k-means中的聚类数量…

C语言——从键盘输人三角形的三个边长 a、b、c,求出三角形的面积。

从键盘输人三角形的三个边长 a、b、c,求出三角形的面积。求三角形的面积用公式areasqrt(s*(s-a)*(s-b)*(s-c)),其中 s1/2(a十bc)。注:要求对输人三角形的三个边长做出有效性判断。 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> #include<math.h> int main…

前置微小信号放大器在生物医学中有哪些应用

前置微小信号放大器在生物医学领域中具有广泛的应用。生物医学信号通常具有较小的振幅和较低的幅频响应&#xff0c;因此需要借助放大器来增强信号以便进行准确的测量、监测和分析。以下是前置微小信号放大器在生物医学中的主要应用。 心电图&#xff08;ECG&#xff09;放大器…

Spring第一课,了解IDEA里面的文件,回顾Cookie和Session,获取Session,Cookie,Header的方式

目录 IDEA第一课&#xff08;熟悉里面内容&#xff09; 建立连接 -RequestMapping 路由映射 请求 1.传递单个参数​编辑 2.多个参数​编辑 3.传递数组 4.传递一个集合&#xff0c;但是这里我们传递的时候发生了500的错误 简单介绍JSON 回顾Cookie和S…

js检测dom变化的方法:MutationObserver

前言 检测一个原生dom的变化,如一个div的颜色,大小,所在位置,内部元素的属性是否变化,更深层dom树上的变化等等。 都可以使用一个window上暴露出来的一个api:MutationObserver 语法 官方地址:MutationObserver.MutationObserver() - Web API 接口参考 | MDN 使用new Mutat…

【大数据】Docker部署HMS(Hive Metastore Service)并使用Trino访问Minio

本文参考链接置顶&#xff1a; Presto使用Docker独立运行Hive Standalone Metastore管理MinIO&#xff08;S3&#xff09;_hive minio_BigDataToAI的博客-CSDN博客 一. 背景 团队要升级大数据架构&#xff0c;需要摒弃hadoop&#xff0c;底层使用Minio做存储&#xff0c;应用…

干货 | 携程酒店基于血缘元数据的数据流程优化实践

作者简介 九号&#xff0c;携程数据技术专家&#xff0c;关注数据仓库架构、数据湖、流式计算、数据治理。 一、背景 元数据MetaData狭义的解释是用来描述数据的数据&#xff0c;广义的来看&#xff0c;除了业务逻辑直接读写处理的那些业务数据&#xff0c;所有其它用来维持整个…

ubuntu22.04 arrch64版操作系统编译zlmediakit

脚本 系统没有cmake&#xff0c;需要通过apt先进行下载&#xff0c;下面的脚本已经包含了 # 安装依赖 gcc-c.x86_64 这个不加的话会有问题 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64 ca…

csrf漏洞修复

漏洞说明&#xff1a;通过篡改请求头中的Referer值依旧能够访问到接口。 通过http请求头里面的Referer随意访问接口 通过下面两个代码类程序来实现你的程序不会被攻击&#xff0c;里面有两个实体&#xff0c;如果你感觉这个程序对你有用&#xff0c;联系我&#xff0c;我私发…

CentOS 7 安装 Weblogic 14 版本

安装JDK程序 注意&#xff1a;安装weblogic前&#xff0c;先安装JDK&#xff01;&#xff08;要求jdk(1.7以上)&#xff09;&#xff1a; 一、创建用户组weblogic及用户weblogic groupadd weblogic useradd -g weblogic weblogic二、将下载好的jdk及weblogic上传至/home/webl…

「首届广州百家新锐企业」名单出炉!数说故事遴选入围

11月20日&#xff0c;由中共广州市委统战部、市工商联、市工信局、市国资委、市科技局联合主办的首届广州百家新锐企业融通创新交流会在广州成功举办。 为推动广州市中小民营企业的创新发展&#xff0c;践行新发展理念&#xff0c;厚植广州产业根基&#xff0c;现场发布首届广…

qt实现播放视屏的时候,加载外挂字幕(.srt文件解析)

之前用qt写了一个在windows下播放视频的软件&#xff0c;具体介绍参见qt编写的视频播放器&#xff0c;windows下使用&#xff0c;精致小巧_GreenHandBruce的博客-CSDN博客 后来发现有些视频没有内嵌字幕&#xff0c;需要外挂字幕&#xff0c;这时候&#xff0c;我就想着把加载…

YOLOv5结合华为诺亚VanillaNet Block模块

🗝️YOLOv5实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv5:我的专业笔记与技术总结   -- YOLOv5轻松上手, 适用技术小白,文章代码齐全,仅需 …

完美解决AttributeError: ‘NoneType‘ object has no attribute ‘append‘

文章目录 一、原始代码二、修改后的代码--最后一行代码append进行了修改总结 一、原始代码 logits_list [] # 创建一个空列表来存储每个logitslabels_list []for i, batch in enumerate(test_tasks):with torch.no_grad():logits, labels, loss, acc self.fast_adapt(batc…

斯坦福大学引入FlashFFTConv来优化机器学习中长序列的FFT卷积

斯坦福大学的FlashFFTConv优化了扩展序列的快速傅里叶变换(FFT)卷积。该方法引入Monarch分解&#xff0c;在FLOP和I/O成本之间取得平衡&#xff0c;提高模型质量和效率。并且优于PyTorch和FlashAttention-v2。它可以处理更长的序列&#xff0c;并在人工智能应用程序中打开新的可…

SQL Server Profiler基础使用

文章目录 SQL Server Profiler基础使用简介如何打开直接打开Microsoft SQL Server Management Studio工具栏打开 配置跟踪新建跟踪跟踪属性配置常规配置事件选择 启动跟踪跟踪时执行脚本跟踪记录 暂停跟踪停止跟踪 SQL Server Profiler基础使用 简介 一个图形界面工具&#x…