Python面试宝典第15题:岛屿数量

题目

        在二维网格地图上,'1' 表示陆地,'0' 表示水域。如果相邻的陆地可以水平或垂直连接,则它们属于同一块岛屿。请进行编码,统计地图上的岛屿数量。比如:下面的二维网格地图,其岛屿数量为3。

基础知识

        解决这类问题的一种常见方法是:深度优先搜索(DFS)或广度优先搜索(BFS)。深度优先搜索和广度优先搜索是图和树型结构中两种基本的遍历算法,广泛应用于各种问题解决场景中,比如:路径查找、图的连通性分析、游戏AI等。下面,我们介绍下深度优先搜索和广度优先搜索的基础知识。

        深度优先搜索是一种探索策略,算法会尽可能深地探索图的分支,直到到达叶子节点或无法继续深入为止,然后回溯以探索其他分支。这个过程类似于树的前序遍历,先访问子节点,再返回访问兄弟节点。深度优先搜索通常使用递归来实现,也可以通过栈来手动模拟递归过程。在遍历过程中,一旦访问到一个未访问过的节点,就标记该节点为已访问,并继续深入访问其子节点。

        广度优先搜索则是从起始节点开始,一层一层地往外探索。先访问离起点最近的所有节点,再访问次近的节点,以此类推。这个过程,类似于树的层次遍历。广度优先搜索主要利用队列数据结构来实现:从根节点开始,将其放入队列中,然后从队列中取出节点并访问;接着,将该节点的所有未访问过的邻接节点放入队列,重复这一过程直到队列为空。

深度优先搜索算法

        我们首先使用深度优先搜索(DFS)算法来求解本题。DFS是一种递归算法,用于遍历或搜索树或图的数据结构。在本题中,我们可以将每个‘1’视为图中的一个节点,相邻的‘1’之间存在边。我们的目标是遍历所有与当前节点相连的陆地节点,并避免重复计数。使用DFS求解本题的主要步骤如下。

        1、初始化计数器。设置一个岛屿计数器,初始值为0。

        2、遍历网格。遍历整个二维网格的每一个元素,当遇到值为‘1’的元素时,进行以下操作。

        (1)增加岛屿计数器的值。

        (2)对该位置调用以下的DFS函数,以探索与之相连的所有陆地。

        (3)在DFS过程中,将访问过的陆地标记为其他值,以防止重复计数。

        3、DFS函数,功能如下。

        (1)输入一个坐标,检查该坐标是否在网格内且值为‘1’,如果不是则返回。

        (2)将当前位置标记为已访问(比如:改为‘2’)。

        (3)递归地对当前位置的上、下、左、右邻居进行DFS,确保只访问未标记的陆地。

        4、完成遍历:当整个网格遍历完成后,计数器的值即为岛屿总数。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def dfs(grid, row, col):if row < 0 or col < 0 or row >= len(grid) or \col >= len(grid[0]) or grid[row][col] != '1':return# 标记为已访问grid[row][col] = '2'# 向下dfs(grid, row + 1, col)# 向上dfs(grid, row - 1, col)# 向右dfs(grid, row, col + 1)# 向左dfs(grid, row, col - 1)def island_count_by_dfs(grid):count = 0for row in range(len(grid)):for col in range(len(grid[0])):if grid[row][col] == '1':count += 1dfs(grid, row, col)return countgrid = [['1', '1', '0', '0', '0'],['1', '1', '0', '0', '0'],['0', '0', '1', '0', '0'],['0', '0', '0', '1', '1']
]
print(island_count_by_dfs(grid))

广度优先搜索算法

        接下来,我们使用广度优先搜索(BFS)算法来求解本题。BFS通过队列逐层探索二维网格地图,标记访问过的陆地,从而逐个发现并计数岛屿。使用BFS求解本题的主要步骤如下。

        1、初始化。设立一个队列用于BFS遍历,以及一个计数器来记录岛屿数量。

        2、遍历网格。遍历整个二维网格,对于每个元素,如果遇到值为‘1’的(表示陆地),进行以下操作。

        (1)增加岛屿计数器。

        (2)将此陆地坐标放入队列中,并将其标记为已访问(比如:改为‘2’)。

        (3)开始BFS,从当前坐标出发,探索所有相连的陆地。

        3、BFS过程,大致步骤如下。

        (1)从队列中取出一个坐标。

        (2)探索其上、下、左、右四个相邻坐标。

        (3)对于每个未访问的陆地邻居,将其标记为已访问,并加入队列。

        (4)重复上述过程,直到队列为空。

        根据上面的算法步骤,我们可以得出下面的示例代码。

from collections import dequedef bfs(grid, row, col):queue = deque([(row, col)])directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]while queue:r, c = queue.popleft()for dr, dc in directions:new_r, new_c = r + dr, c + dcif 0 <= new_r < len(grid) and 0 <= new_c < len(grid[0]) \and grid[new_r][new_c] == '1':grid[new_r][new_c] = '2'queue.append((new_r, new_c))def island_count_by_bfs(grid):island_count = 0for row in range(len(grid)):for col in range(len(grid[0])):if grid[row][col] == '1':island_count += 1bfs(grid, row, col)return island_countgrid = [['1', '1', '0', '0', '0'],['1', '1', '0', '0', '0'],['0', '0', '1', '0', '0'],['0', '0', '0', '1', '1']
]
print(island_count_by_bfs(grid))

总结

        可以看到,无论是DFS还是BFS,时间复杂度均为O(M * N),空间复杂度在最坏情况下为O(M)或O(N),取决于地图的具体布局和岛屿的分布情况。其中,M是网格的行数,N是网格的列数。

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

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

相关文章

简约的悬浮动态特效404单页源HTML码

源码介绍 简约的悬浮动态特效404单页源HTML码,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head><meta charset="utf-8&q…

高性能、安全、低碳绿色的趋势下,锐捷网络发布三擎云办公解决方案 3.0

桌面虚拟化作为云时代的主流和热门技术&#xff0c;已经取得了广泛应用。随着生成式 AI 爆炸式发展&#xff0c;CSDN 看到&#xff0c;人工智能正在引发计算、开发、交互三大范式的全面升级&#xff0c;技术开发或将迎来一次全新的科技变革周期&#xff0c;因此 VDI 云桌面随之…

组队学习——支持向量机

本次学习支持向量机部分数据如下所示 IDmasswidthheightcolor_scorefruit_namekind 其中ID&#xff1a;1-59是对应训练集和验证集的数据&#xff0c;60-67是对应测试集的数据&#xff0c;其中水果类别一共有四类包括apple、lemon、orange、mandarin。要求根据1-59的数据集的自…

Day16_集合与迭代器

Day16-集合 Day16 集合与迭代器1.1 集合的概念 集合继承图1.2 Collection接口1、添加元素2、删除元素3、查询与获取元素不过当我们实际使用都是使用的他的子类Arraylist&#xff01;&#xff01;&#xff01; 1.3 API演示1、演示添加2、演示删除3、演示查询与获取元素 2 Iterat…

[数据分析]脑图像处理工具

###############ATTENTION&#xff01;############### 非常需要注意软件适配的操作系统&#xff01;有些仅适用于Linux&#xff0c;可以点进各自软件手册查看详情。 需要自行查看支持的影像模态。 代码库和软件我没有加以区分。 不是专门预处理的博客&#xff01;&#xf…

HDU1005——Number Sequence,HDU1006——Tick and Tick,HDU1007——Quoit Design

目录 HDU1005——Number Sequence 题目描述 超时代码 代码思路 正确代码 代码思路 HDU1006——Tick and Tick 题目描述 运行代码 代码思路 HDU1007——Quoit Design 题目描述 运行代码 代码思路 HDU1005——Number Sequence 题目描述 Problem - 1005 超时代码…

QtC++ 设计模式(五)——状态模式

状态模式 序言理解源码 序言 设计模式只是一个抽象的设计模式方法&#xff0c;并不是一个固定使用的搭配&#xff0c;就算是普通switch语句&#xff0c;Map&#xff0c;乃至状态机都是状态模式的其中一种实现方法 状态模式看起来好像和策略模式差不多&#xff0c;主要是其的侧…

神经网络之多层感知机

目录 一、全连接层&#xff1a;二、单层感知机概念&#xff1a;三、多层感知机概念&#xff1a; 一、全连接层&#xff1a; 在神经网络中&#xff0c;全连接层就是每个神经元都与上一层的所有神经元相连接&#xff0c;即每个神经元都接收上一层所有神经元的输入&#xff0c;并…

分布式存储之 ceph 管理操作

一.资源池 Pool 管理 我们已经完成了 Ceph 集群的部署&#xff0c;但是我们如何向 Ceph 中存储数据呢&#xff1f;首先我们需要在 Ceph 中定义一个 Pool 资源池。Pool 是 Ceph 中存储 Object 对象抽象概念。我们可以将其理解为 Ceph 存储上划分的逻辑分区&#xff0c;Pool 由…

git使用-命令行+VS Code结合使用

一、Git常用命令 // 显示当分支的状态。它会列出已修改、已暂存和未跟踪的文件 git status// 列出本地仓库中所有的分支&#xff0c;其中会特殊显示当前所在分支 git branch// 在当前分支的基础上创建一个新的分支&#xff0c;并切换到这个新的分支上 git checkout -b 新分支…

Python创建Excel表和读取Excel表的基础操作

下载openpyxl第三方库 winr打开命令行输入cmd 这个如果不行可以试试其他方法&#xff0c;在运行Python代码的软件里也有直接下载的地方&#xff0c;可以上网搜索 创建Excel表 示例代码&#xff1a;最后要记得保存&#xff0c;可以加一句提示语句。 import openpyxl lst[100,…

文件IO(Ubuntu)

文件IO 目的 将数据写入文件中 与标准IO的区别 &#xff08;为什么要学习文件IO&#xff09; 标准IO只能操作普通文件和特殊的管道文件 文件IO能操作几乎所有的的文件 缓存区的目的 标准IO有缓存区 文件IO没有缓存区 根据右图描述 标准IO 文件IO buffer缓存区 有缓存区…

【SASS/SCSS(三)】样式的复用与动态计算(@mixin和@function)

目录 一、mixin 1、定义复用的样式代码&#xff0c;接受传参&#xff0c;搭配include使用。 位置传参 关键词传参 ...语法糖接受传入的任意参数 2、在mixin中使用content&#xff0c;获取外部对mixin的追加内容 二、function 三、字符串——值得注意的点 很多时候&#…

水域救援装备的详细简介_鼎跃安全

水域救援行动需要救援人员配备全面、专业的装备&#xff0c;以应对各种复杂的水域环境和救援任务。水域救援套装应运而生&#xff0c;它集合了水域救援所需的各类关键装备&#xff0c;为救援人员提供全方位的保护和辅助&#xff0c;确保数援行动的高效与安全。 水域救援头盔&am…

Visual Studio 2022美化

说明&#xff1a; VS版本&#xff1a;Visual Studio Community 2022 背景美化 【扩展】【管理扩展】搜索“ClaudiaIDE”&#xff0c;【下载】&#xff0c;安装完扩展要重启VS 在wallhaven下载壁纸图片作为文本编辑器区域背景图片 【工具】【选项】搜索ClaudiaIDE&#xff…

Dify中的高质量索引模式实现过程

思考在什么情况下会使用到高质量索引模式呢?第1种情况是在知识库中上传文档,文档被拆分为段落后需要进行编码(增加);第2种情况是在召回测试的时候,需要对query进行编码(查询);第3种情况是当文档中的段落增加和更新时需要进行编码(增加和更新)。索引模式是针对知识库…

【Qt】之【Bug】error:C1083 无法打开包括文件

背景 a.cpp引用b.h正常&#xff0c;但是a.h引用b.h就报 “无法打开包括文件”的错误 分析 查看“编译输出”&#xff0c;显示不是a.h引起的错误&#xff0c;而是C插件&#xff0c; 查看后发现&#xff0c;C插件引用了a所在插件pro&#xff0c;但是没有引用a依赖的b所在的插件…

vscode 中python 支持自动跳转

随笔记录 目录 1. 背景介绍 2. 解决方案 1. 背景介绍 vscode 远程ssh 打开python 脚本无法自动跳转 2. 解决方案 安装python 插件即可。 至此&#xff0c;已完成vscode 上py 文件支持自动跳转功能

Mac Electron 应用如何进行签名(signature)和公证(notarization)?

最近很多客户反映&#xff0c;从官网下载的Mac Electron应用打不开&#xff0c;直接报病毒&#xff0c;类似于这种&#xff1a; 这是因为在MacOS 10.14.5之后&#xff0c;如果应用没有在苹果官方平台进行公证notarization(我们可以理解为安装包需要审核&#xff0c;来判断是否存…

网络安全-等级保护制度介绍

一、等保发展历程 &#xff08;1&#xff09;1994国务院147号令 第一次提出等级保护概念&#xff0c;要求对信息系统分等级进行保护 &#xff08;2&#xff09;1999年GB17859 国家强制标准发布&#xff0c;信息系统等级保护必须遵循的法规 &#xff08;3&#xff09;2005年公安…