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://www.mzph.cn/bicheng/47895.shtml

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

相关文章

国产化低功耗HDMI转VGA方案,大量出货产品,广泛应用在显示器以及广告机产品

芯片描述&#xff1a; 兼具高性能和低成本效益的优点&#xff0c;是一款可以将高清视频 HDMI1.4 数字信号转换成 VGA 模拟信号输出的芯片。不需要提供外部电源&#xff0c;ICNM7301 就可以在正常模式下使用&#xff1b;ICNM7301 广 泛适用于各种市场系统和显示应用体系&#x…

机器学习包含子领域

机器学习是人工智能中最活跃的研究领域之一,它通过算法使计算机能够从数据中学习并做出决策。本文将详细介绍机器学习的各个子领域,包括它们的定义、主要方法和应用场景。 1. 监督学习 定义: 监督学习是一种机器学习类型,其中模型从标记的训练数据中学习,以便对新的、未标…

EasyExcel导入导出数据类型转换

前言&#xff1a; 1、基本数据类型转换&#xff1a;当前原始的数据类型是interger类型&#xff0c;需要在导出时将其映射为对应的字符串&#xff0c;并且导入时可以将字符串重新映射为interger类型。 2、时间格式转换&#xff1a;数据从数据库中获取的类型为LocalDate类型&…

Yum包下载

1. 起因 内网有一台服务器需要升级php版本,维护的同学又不想二进制安装.服务器只有一个光盘的yum仓库 2. 解决方法 解决思路如下: 外网找一台机器配置php8.3.8的仓库外网服务器下载软件集并打包内网服务器上传并解压实现升级 2.1 下载php8.3.8仓库 配置php仓库 rootcent…

【视频讲解】神经网络、Lasso回归、线性回归、随机森林、ARIMA股票价格时间序列预测|附代码数据

全文链接&#xff1a;https://tecdat.cn/?p37019 分析师&#xff1a;Haopeng Li 随着我国股票市场规模的不断扩大、制度的不断完善&#xff0c;它在金融市场中也成为了越来越不可或缺的一部分。 【视频讲解】神经网络、Lasso回归、线性回归、随机森林、ARIMA股票价格时间序列…

新时代多目标优化【数学建模】领域的极致探索——数学规划模型

目录 例1 1.问题重述 2.基本模型 变量定义&#xff1a; 目标函数&#xff1a; 约束条件&#xff1a; 3.模型分析与假设 4.模型求解 5.LINGO代码实现 6.结果解释 ​编辑 7.敏感性分析 8.结果解释 例2 奶制品的销售计划 1.问题重述 ​编辑 2.基本模型 3.模…

【网络】Socket编程

文章目录 正确理解端口号理解源IP地址和目的IP地址认识端口号端口号和进程ID 理解Socket网络字节序socket编程接口创建socket套接字bind绑定套接字listen建立监听accept接受连接connect建立连接sendto发送数据接收数据close关闭套接字 sockaddr结构体 正确理解端口号 理解源IP…

分布式唯一id的7种方案

背景 为什么需要使用分布式唯一id&#xff1f; 如果我们的系统是单体的&#xff0c;数据库是单库&#xff0c;那无所谓&#xff0c;怎么搞都行。 但是如果系统是多系统&#xff0c;如果id是和业务相关&#xff0c;由各个系统生成的情况下&#xff0c;那每个主机生成的主键id就…

Linux网络 -- TCP FIN包发送超时时间设置

使用 SO_LINGER 选项控制FIN包发送的超时时间 技术背景 在TCP连接中&#xff0c;当应用程序调用 close 或 shutdown 函数关闭一个socket时&#xff0c;操作系统内核会发送一个FIN包以通知对端连接即将关闭。默认情况下&#xff0c;内核会等待所有未发送的数据发送完毕后再发送…

使用崖山YMP 迁移 Oracle/MySQL 至YashanDB 23.2 验证测试

前言 首届YashanDB「迁移体验官」开放后&#xff0c;陆续收到「体验官」们的投稿&#xff0c;小崖在此把优秀的投稿文章分享给大家~今天分享的用户文章是《使用崖山YMP 迁移 Oracle/MySQL 至YashanDB 23.2 验证测试》&#xff08;作者&#xff1a;尚雷&#xff09;&#xff0c…

PHP宠物店萌宠小程序系统源码

&#x1f43e;萌宠生活新方式&#x1f43e; &#x1f3e1;【一键直达萌宠世界】 你是否也梦想着拥有一家随时能“云撸猫”、“云吸狗”的神奇小店&#xff1f;现在&#xff0c;“宠物店萌宠小程序”就是你的秘密花园&#xff01;&#x1f31f;只需轻轻一点&#xff0c;就能瞬…

什么是股指期货交割?股指期货交割的例子

股指期货交割是指在股指期货合约到期时&#xff0c;投资者需要按照合约规定完成的结算过程。与一般的商品期货、国债期货或外汇期货不同&#xff0c;股指期货采用的是现金交割方式。 股指期货交割的方式 【现金交割】股指期货的交割不需要实际交割一篮子股票指数成分股。相反…

(社恐福音)用python写一个定时弹窗功能

背景 背景是换了一个工作&#xff0c;需要点外卖了 写代码太认真的时候又经常忘记 这时候就需要一个闹钟 手机闹钟声音太大 会影响他人 所以用python 写一个弹窗功能&#xff0c;只影响自己 效果图 原理 管理列表和定时功能通过windows自带的计划完成 python程序不用占用后台…

js中! 、!!、?.、??、??=的用法及使用场景

js中! 、 !. 、!、?.、.?、??、??的用法及使用场景 !!!?.??????、?? 区别 !. &#xff08;ts&#xff09;注意 ! (非空断言符号) 用于取反一个布尔值或将一个值转换为布尔类型并取反 const a true; const b false; const value !a; // false const value !…

https和http区别

1、安全性 HTTP信息是明文传输&#xff0c;而HTTPS则通过SSL/TLS协议进行加密传输&#xff0c;确保数据传输的安全性。HTTPS可以验证服务器身份&#xff0c;防止中间人攻击&#xff0c;保护数据的完整性和保密性。 2、端口号 HTTP默认使用80端口&#xff0c;而HTTPS默认使用…

最佳实践:设计思维:“6+1”迭代过程的创新实践丨IDCF

谢志萌 研发效能&#xff08;DevOps&#xff09;工程师&#xff08;中级&#xff09;认证学员 一、前言 “有效的Devops关键在于专注于人员和文化&#xff0c;而不仅仅是工具和技术。” -John Willis 随着数字化转型的加速&#xff0c;组织越来越依赖于快速、高效的软件交…

7月18日学习打卡,数据结构堆

hello大家好呀&#xff0c;本博客目的在于记录暑假学习打卡&#xff0c;后续会整理成一个专栏&#xff0c;主要打算在暑假学习完数据结构&#xff0c;因此会发一些相关的数据结构实现的博客和一些刷的题&#xff0c;个人学习使用&#xff0c;也希望大家多多支持&#xff0c;有不…

ARM架构(二)—— arm v7/v8/v9寄存器介绍

1、ARM v7寄存器 1.1 通用寄存器 V7 V8开始 FIQ个IRQ优先级一样&#xff0c; 通用寄存器&#xff1a;31个 1.2 程序状态寄存器 CPSR是程序状态毒存器&#xff0c;保存条件标志位&#xff0c;中断禁止位&#xff0c;当前处理器模式等控制和状态位。每种异常模式下还存在SPSR&…

《系统架构设计师教程(第2版)》第12章-信息系统架构设计理论与实践-02-信息系统架构

文章目录 1. 概述1.1 信息系统架构&#xff08;ISA&#xff09;1.2 架构风格 2. 信息系统架构分类2.1 信息系统物理结构2.1.1 集中式结构2.1.2 分布式结构 2.2 信息系统的逻辑结构1&#xff09;横向综合2&#xff09;纵向综合3&#xff09;纵横综合 3. 信息系统架构的一般原理4…

Pandas教程:近万字讲解在Pandas中如何操作Excel

目录 1. 安装与配置 2. 读取Excel文件 2.1 基本用法 2.2 指定工作表 2.3 指定单元格范围 3. 数据检查与预处理 3.1 查看数据的基本信息 3.2 数据类型检查与转换 3.3 检查缺失值 3.4 处理缺失值 4. 数据清洗与转换 4.1 重命名列 4.2 删除重复数据 4.3 数据替换 4…