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…

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…

使用崖山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程序不用占用后台…

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…

Android使用ANativeWindow更新surfaceView内容最简Demo

SurfaceView简介 SurfaceView对比View的区别 安卓的普通VIew,都依赖于当前Activity的Window的surface&#xff0c;这个surface用于承载view树从底到顶绘制出来的所有内容&#xff0c;因此任何一个view需要更新时&#xff0c;都需要把所有view中底到顶进行更新&#xff0c;即使使…

解决:Linux上SVN 1.12版本以上无法直接存储明文密码

问题&#xff1a;今天在Linux机器上安装了SVN&#xff0c;作为客户端使用&#xff0c;首次执行SVN相关操作&#xff0c;输入账号密码信息后&#xff0c;后面再执行SVN相关操作&#xff08;比如"svn update"&#xff09;还是每次都需要输入密码。 回想以前在首次输入…

Python进阶(4)--正则表达式

正则表达式 在Python中&#xff0c;正则表达式&#xff08;Regular Expression&#xff0c;简称Regex&#xff09;是一种强大的文本处理工具&#xff0c;它允许你使用一种特殊的语法来匹配、查找、替换字符串中的文本。 在这之前&#xff0c;还记得之前我们是通过什么方法分割…

[论文笔记] pai-megatron-patch Qwen2-CT 长文本rope改yarn

更改: # Copyright (c) 2024 Alibaba PAI and Nvidia Megatron-LM Team. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License a…

【系统架构设计】数据库系统(二)

数据库系统&#xff08;二&#xff09; 数据库模式与范式数据库设计数据库设计的方法数据库设计的基本步骤 事务管理并发控制故障和恢复 备份与恢复分布式数据库系统数据仓库数据挖掘NoSQL大数据 数据库模式与范式 数据库设计 数据库设计的方法 目前已有的数据库设计方法可分…

element UI :el-table横向列内容超出宽度,滚动条不显示问题

是否能解决你问题的前提 **看到这篇文章的解决问题的方案之前&#xff0c;请先回忆你是否在项目中的全局样式或者私有组件中去单独设置过滚动条样式。如果有 请继续往下看&#xff1a;**单独设置过滚动条样式代码实例&#xff1a; ::-webkit-scrollbar {/*滚动条整体样式*/wi…

layui 让table里的下拉框不被遮挡

记录&#xff1a;layui 让table里的下拉框不被遮挡 /* 这个是让table里的下拉框不被遮挡 */ .goods_table .layui-select-title,.goods_table .layui-select-title input{line-height: 28px;height: 28px; }.goods_table .layui-table-cell {overflow: visible !important; }.…

【Django】网上蛋糕项目商城-注册,登录,修改用户信息,退出功能

概念 通过以上多篇文章的讲解&#xff0c;对该项目的功能已经实现了很多&#xff0c;本文将对该项目的用户注册&#xff0c;登录&#xff0c;修改用户信息&#xff0c;以及退出等功能的实现。 注册功能实现 点击head.html头部页面的注册按钮&#xff0c;触发超链接跳转至use…