LeetCode100 力扣热题100 岛屿数量

embedded/2025/2/22 17:59:53/

题目背景

这个问题是岛屿数量问题,给定一个由 '1'(陆地)和 '0'(水域)组成的网格,计算并返回其中岛屿的数量。一个岛屿是由相邻的陆地组成,陆地可以是水平或垂直相邻。

思路

我们可以使用深度优先搜索(DFS)来遍历每个岛屿。DFS 会遍历每个 '1' 组成的连通区域,将其标记为 '0',表示已经访问过。每次遇到一个 '1' 时,都会启动一次 DFS 来将整片岛屿都标记掉,并增加岛屿计数。

关键步骤

1. 遍历网格:遍历每个网格单元,如果它是 '1',表示发现一个新的岛屿。

2. 深度优先搜索(DFS):每发现一个新的岛屿,从这个 '1' 开始,使用 DFS 标记这个岛屿的所有陆地为 '0',避免重复计算。

3. 岛屿计数:每次启动 DFS 之后,岛屿计数增加。

代码注释

class Solution {public:// 主函数,计算岛屿的数量int numIslands(vector<vector<char>>& grid) {int ans = 0;  // 用于计数岛屿数量// 遍历网格的每个位置for(int i = 0; i < grid.size(); i++) {  // 遍历每一行for(int j = 0; j < grid[0].size(); j++) {  // 遍历每一列if(grid[i][j] == '1') {  // 找到一个岛屿ans++;  // 增加岛屿计数dfs(grid, i, j);  // 启动 DFS 来标记整个岛屿}}}return ans;  // 返回岛屿的数量}// 深度优先搜索函数,用来标记岛屿中的每个陆地void dfs(vector<vector<char>>& grid, int i, int j) {// 如果位置越界或者当前点是水域('0'),则返回if(i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] == '0') {return;}// 将当前陆地标记为水域('0'),表示已访问grid[i][j] = '0';// 递归调用 DFS,访问四个方向的邻居(上下左右)dfs(grid, i + 1, j);  // 向下dfs(grid, i - 1, j);  // 向上dfs(grid, i, j + 1);  // 向右dfs(grid, i, j - 1);  // 向左}};

思路总结

1. 岛屿计数:我们遍历整个网格,遇到 '1' 就意味着发现了一个新的岛屿。然后启动 DFS,将这个岛屿标记掉。

2. DFS 标记岛屿:从当前 '1' 开始,DFS 会向上下左右四个方向扩展,找到所有连接的 '1',并将它们标记为 '0',表示已访问。

3. 递归边界条件:DFS 的递归条件判断是,越界或者遇到 '0'(水域)就返回,不再继续深入。

运行步骤

假设给定的 grid 是一个 4x5 的二维矩阵:

grid = [

  ['1', '1', '1', '0', '0'],

  ['1', '1', '0', '0', '0'],

  ['0', '0', '1', '0', '0'],

  ['0', '0', '0', '1', '1']

]

1. 初始化

• ans = 0,表示岛屿数量初始化为 0。

2. 遍历网格

1. 第一行: ['1', '1', '1', '0', '0']

• grid[0][0] = '1',启动 DFS,ans++,ans = 1,然后将岛屿位置 '1' 转换为 '0'。

• DFS 会标记 grid[0][0], grid[0][1], grid[0][2] 为 '0'。

2. 第二行: ['1', '1', '0', '0', '0']

• grid[1][0] = '1',但因为之前 DFS 已经把其标记为 '0',所以跳过。

• grid[1][1] = '1',也被标记为 '0'。

3. 第三行: ['0', '0', '1', '0', '0']

• grid[2][2] = '1',启动 DFS,ans++,ans = 2,然后将岛屿位置 '1' 转换为 '0'。

• DFS 会标记 grid[2][2] 为 '0'。

4. 第四行: ['0', '0', '0', '1', '1']

• grid[3][3] = '1',启动 DFS,ans++,ans = 3,然后将岛屿位置 '1' 转换为 '0'。

• DFS 会标记 grid[3][3], grid[3][4] 为 '0'。

3. 返回结果

• 最终 ans = 3,表示网格中有 3 个岛屿。

边界条件和优化

1. 空网格:如果 grid 是一个空矩阵,代码会自动跳过,因为 grid.size() 为 0,不会进入循环。

2. 大网格:该算法使用了深度优先搜索(DFS),时间复杂度为 O(m * n),其中 m 和 n 分别是矩阵的行数和列数。对于每个节点,DFS 会被访问一次,因此时间复杂度是线性的。

总结

岛屿数量的计算:通过 DFS 遍历每个 '1',每遇到一个未访问过的陆地(岛屿)就启动 DFS 来将其完全标记。

复杂度:时间复杂度为 O(m * n),空间复杂度为 O(m * n)(递归栈的深度)。

这种方法能够高效地计算岛屿数量,同时避免重复计数岛屿。


http://www.ppmy.cn/embedded/164404.html

相关文章

nginx配置:nginx.conf配置文件

nginx.conf配置文件说明 基本结构 全局块&#xff1a;位于最外层&#xff0c;定义影响整个Nginx服务器的设置。事件块&#xff1a;配置网络连接相关的设置。HTTP块&#xff1a;定义HTTP服务器以及反向代理、负载均衡等特性。Server块&#xff1a;定义虚拟主机&#xff0c;即响…

汽车长期不保养的危害

汽车两三年不保养会对车辆的多个系统和部件产生严重危害&#xff0c;以下将详细阐述&#xff1a; 发动机系统 润滑系统问题 机油在发动机中起着润滑、冷却、清洁和密封的重要作用。长时间不更换机油&#xff0c;机油会因氧化、污染等原因变质&#xff0c;其润滑性能大幅下降。…

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(四) -> 常见组件(二) -> tabs

目录 1 -> 创建Tabs 2 -> 设置Tabs方向 3 -> 设置样式 4 -> 显示页签索引 5 -> 场景示例 1 -> 创建Tabs 在pages/index目录下的hml文件中创建一个Tabs组件。 <!-- index.hml --> <div class"container" ><tabs> <tab-…

深入理解Zookeeper:分布式系统的协调者

引言 在现代分布式系统中&#xff0c;协调和管理多个节点之间的状态和行为是一个复杂且关键的任务。Zookeeper作为一个分布式协调服务&#xff0c;为开发者提供了一种高效、可靠的方式来处理分布式系统中的一致性问题。本文将介绍Zookeeper的基本概念、使用场景以及如何通过示…

Git是什么

简单介绍&#xff1a; Git是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改&#xff0c;特别是在多人协作开发的环境中。 Key: 分布式 版本控制 系统 最常用于软件开发&#xff0c;但也可以用于管理任何类型的文件和文件夹。 Git帮助团队跟踪和管理文件的历史版本&a…

前端(AJAX)学习笔记(CLASS 2):图书管理案例以及图片上传

* BootStrap弹框 功能&#xff1a;不离开当前页面&#xff0c;显示单独内容&#xff0c;供用户操作 步骤&#xff1a; 1、引入bootstrap.css和bootstrap.js 2、准备弹框标签&#xff0c;确认结构 3、通过自定义属性&#xff0c;控制弹框的显示和隐藏 其中的bootstrap.css…

MAC快速本地部署Deepseek (win也可以)

MAC快速本地部署Deepseek (win也可以) 下载安装ollama 地址: https://ollama.com/ Ollama 是一个开源的大型语言模型&#xff08;LLM&#xff09;本地运行框架&#xff0c;旨在简化大模型的部署和管理流程&#xff0c;使开发者、研究人员及爱好者能够高效地在本地环境中实验和…

ML.NET库学习009:花卉图像分类模型

文章目录 ML.NET库学习009&#xff1a;花卉图像分类模型进行图像分类训练的实现功能分析代码结构核心组件示例输出代码实现详细步骤说明注意事项 进行图像分类预测的实现主要目的原理概述实现的主要功能主要流程步骤使用的主要函数和方法关键技术功能详细解读&#xff08;1&…