力扣第200题“岛屿数量”

关注微信公众号 数据分析螺丝钉 免费领取价值万元的python/java/商业分析/数据结构与算法学习资料

在本篇文章中,我们将详细解读力扣第200题“岛屿数量”。通过学习本篇文章,读者将掌握如何使用深度优先搜索(DFS)和广度优先搜索(BFS)来解决这一问题,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释,以便于理解。

问题描述

力扣第200题“岛屿数量”描述如下:

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和垂直方向上相邻的陆地连接形成。

示例 1:

输入: [
['1','1','1','1','0'],
['1','1','0','1','0'],
['1','1','0','0','0'],
['0','0','0','0','0']
]
输出: 1

示例 2:

输入: [
['1','1','0','0','0'],
['1','1','0','0','0'],
['0','0','1','0','0'],
['0','0','0','1','1']
]
输出: 3

解题思路

方法一:深度优先搜索(DFS)
  1. 初步分析

    • 使用DFS遍历二维网格,从每个未访问的陆地开始,遍历所有相连的陆地并将其标记为已访问。
    • 每次启动新的DFS遍历时,计数器加一。
  2. 步骤

    • 遍历二维网格的每个位置。
    • 对于每个未访问的陆地,启动DFS遍历,并将其相连的所有陆地标记为已访问。
代码实现
def numIslands(grid):if not grid:return 0def dfs(grid, i, j):if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] == '0':returngrid[i][j] = '0'dfs(grid, i+1, j)dfs(grid, i-1, j)dfs(grid, i, j+1)dfs(grid, i, j-1)count = 0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j] == '1':dfs(grid, i, j)count += 1return count# 测试案例
print(numIslands([['1','1','1','1','0'],['1','1','0','1','0'],['1','1','0','0','0'],['0','0','0','0','0']
]))  # 输出: 1print(numIslands([['1','1','0','0','0'],['1','1','0','0','0'],['0','0','1','0','0'],['0','0','0','1','1']
]))  # 输出: 3
方法二:广度优先搜索(BFS)
  1. 初步分析

    • 使用BFS遍历二维网格,从每个未访问的陆地开始,使用队列遍历所有相连的陆地并将其标记为已访问。
    • 每次启动新的BFS遍历时,计数器加一。
  2. 步骤

    • 遍历二维网格的每个位置。
    • 对于每个未访问的陆地,启动BFS遍历,并将其相连的所有陆地标记为已访问。
代码实现
from collections import dequedef numIslands(grid):if not grid:return 0def bfs(grid, i, j):queue = deque([(i, j)])while queue:x, y = queue.popleft()if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] == '0':continuegrid[x][y] = '0'queue.append((x+1, y))queue.append((x-1, y))queue.append((x, y+1))queue.append((x, y-1))count = 0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j] == '1':bfs(grid, i, j)count += 1return count# 测试案例
print(numIslands([['1','1','1','1','0'],['1','1','0','1','0'],['1','1','0','0','0'],['0','0','0','0','0']
]))  # 输出: 1print(numIslands([['1','1','0','0','0'],['1','1','0','0','0'],['0','0','1','0','0'],['0','0','0','1','1']
]))  # 输出: 3

复杂度分析

  • 时间复杂度
    • DFS:O(m * n),其中 m 和 n 分别是二维网格的行数和列数。每个位置只访问一次。
    • BFS:O(m * n),同样,每个位置只访问一次。
  • 空间复杂度
    • DFS:O(m * n),用于递归调用栈。
    • BFS:O(min(m, n)),用于队列。

模拟面试问答

问题 1:你能描述一下如何解决这个问题的思路吗?

回答:我们可以使用深度优先搜索(DFS)和广度优先搜索(BFS)来解决这个问题。使用DFS从每个未访问的陆地开始,遍历所有相连的陆地并将其标记为已访问。每次启动新的DFS遍历时,计数器加一。BFS的思路类似,只是使用队列遍历相连的陆地。

问题 2:为什么选择使用深度优先搜索和广度优先搜索来解决这个问题?

回答:DFS和BFS都是图遍历的经典算法,适用于处理连通性问题。这个问题本质上是一个连通分量的计数问题,使用DFS和BFS都可以高效地解决。

问题 3:你的算法的时间复杂度和空间复杂度是多少?

回答:两种方法的时间复杂度都是 O(m * n),其中 m 和 n 分别是二维网格的行数和列数。DFS的空间复杂度为 O(m * n),用于递归调用栈;BFS的空间复杂度为 O(min(m, n)),用于队列。

问题 4:在代码中如何处理边界情况?

回答:在递归或队列中处理边界情况,检查当前节点是否在网格范围内,如果不在范围内或已经是水(‘0’),则跳过。

问题 5:你能解释一下深度优先搜索和广度优先搜索的工作原理吗?

回答:深度优先搜索(DFS)是一种图遍历算法,优先访问一个节点的所有子节点,再访问其兄弟节点。广度优先搜索(BFS)也是一种图遍历算法,优先访问一个节点的所有兄弟节点,再访问其子节点。两种算法都可以有效地遍历图的所有连通分量。

问题 6:在代码中如何确保返回的结果是正确的?

回答:通过从每个未访问的陆地开始,使用DFS或BFS遍历所有相连的陆地,并将其标记为已访问,确保每次新的遍历都计数一次,最终返回计数器的值。

问题 7:你能举例说明在面试中如何回答优化问题吗?

回答:在面试中,如果面试官问到如何优化算法,我会首先分析当前算法的瓶颈,如时间复杂度和空间复杂度,然后提出优化方案。例如,可以通过减少不必要的边界检查来提高性能,或使用更高效的数据结构来优化空间复杂度。解释其原理和优势,最后提供优化后的代码实现。

问题 8:如何验证代码的正确性?

回答:通过运行代码并查看结果,验证返回的岛屿数量是否正确。可以使用多组测试数据,包括正常情况和边界情况,确保代码在各种情况下都能正确运行。例如,可以在测试数据中包含多个岛屿和水域,确保代码结果正确。

问题 9:你能解释一下解决岛屿数量问题的重要性吗?

回答:解决岛屿数量问题在地理信息系统和图像处理等领域具有重要意义。通过分析岛屿的分布,可以帮助我们理解地形和水文特征。在计算机科学中,连通分量的计数问题也是常见的图算法问题,通过学习和应用DFS和BFS,可以提高解决问题的能力。

问题 10:在处理大数据集时,算法的性能如何?

回答:算法的性能取决于二维网格的大小。在处理大数据集时,通过优化DFS和BFS的实现,可以显著提高算法的性能。例如,通过优化递归调用栈的深度和队列的实现,可以减少时间和空间复杂度,从而提高算法的效率。

总结

本文详细解读了力扣第200题“岛屿数量”,通过使用深度优先搜索(DFS)和广度优先搜索(BFS)高效地解决了这一问题,并提供了详细的解释和模拟面试问答。希望读者通过本文的学习,能够在力扣刷题的过程中更加得心应手。

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

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

相关文章

使用nodejs/exceljs读取、操作、写入excel文件

现在edge已经不支持activexobject了&#xff0c;如果想用javascript操作excel文件&#xff0c;基本上只能用nodejs了。下面的代码就是用nodejs操作excel文件的可用方法&#xff0c;读取每个cell&#xff0c;设置颜色。 // save this content as excel.js file // # npm i exce…

芯片环氧胶可以提供一定的耐盐雾耐腐蚀效果!

芯片环氧胶&#xff08;或称为环氧树脂胶&#xff09;在电子封装和保护应用中确实能提供一定的耐盐雾和耐腐蚀效果。 环氧树脂因为其出色的粘接性能、机械强度以及良好的化学稳定性&#xff0c;被广泛用于电子封装领域&#xff0c;尤其是芯片固定和保护。在面对盐雾腐蚀或恶劣…

使用RV1126交叉编译工具链交叉编译opencv,c++代码直接调用VideoCapture 读取摄像头数据

使用RV1126交叉编译工具链交叉编译opencv&#xff0c;rv1126直接调用VideoCapture 读取摄像头数据 前言环境一、ubantu安装二、交叉编译工具安装三、cmake升级四、ffmpeg安装五、opencv安装六、c代码测试&#xff08;上板运行&#xff09; 前言 交叉编译是一种将软件在操作系统…

从零开始利用树莓派+扬声器,实现简单的蓝牙音箱,手机连接放歌

背景 树莓派4B自带蓝牙和Wifi, 无需外接 USB dongle; 蓝牙最常见的应用是近距离传输数据,比如蓝牙传文件,蓝牙音箱等。正好家里有个普通的usb供电的便携音箱; 本文用树莓派蓝牙+普通音箱,实现简单的蓝牙音箱。 大致分为三个部分: kernel/driver层的ALSA驱动框架蓝牙音…

43、Flink 自定义窗口触发器代码示例

1、方法说明 1&#xff09;onElement() 方法在每个元素被加入窗口时调用。 返回 TriggerResult 来决定 trigger 如何应对到达窗口的事件 CONTINUE: 什么也不做 FIRE: 触发计算 PURGE: 清空窗口内的元素 FIRE_AND_PURGE: 触发计算&#xff0c;计算结束后清空窗口内的元素 2&a…

关于docker无法正常下载镜像的问题

文章目录 之前还可以正常下载镜像&#xff0c;但是一段时间之后就无法下载了&#xff0c;猜测可能是政治原因&#xff0c;无法连接到国外服务器&#xff0c;所以我设置了阿里云的镜像加速器。 配置方法如下&#xff1a; 前往阿里云&#xff08;https://help.aliyun.com/zh/acr/…

ATA-3040C功率放大器的正确使用方法

功率放大器是一种用于增强电信号功率的重要设备。正确使用功率放大器可以确保信号的稳定放大&#xff0c;并避免设备损坏。下面将介绍功率放大器的正确使用方法。 确定输入信号的功率范围&#xff1a;在使用功率放大器之前&#xff0c;需要确定输入信号的功率范围。过大的输入功…

Python 最强的5个高级函数,你会几个?

Python是一门灵活而强大的编程语言&#xff0c;具有丰富的内置函数和库。今天&#xff0c;我们将深入探讨五个非常有用的Python高级函数。这些函数不仅能够简化代码&#xff0c;还能提高代码的可读性和可维护性。 首先&#xff0c;了解下什么是高级函数&#xff1f; 高级函数…

C# —— 字符串拼接

字符串拼接的方式一 之前的算术运算符 只是用来数值类型的相加 主要做的是数学的运算 // 而string 不存在算数运算 但是可以通过加号 进行拼接 string str "123" 字符串拼接 str str "456"; Console.WriteLine(str); // "123456&q…

博客摘录「 YOLOv5模型剪枝压缩」2024年5月11日

添加L1正则来约束BN层系数 语义边缘检测和语义分割的关系调研结果为&#xff0c;语义信息可以用来增强语义分割的效果&#xff0c;也有一定的优点和采用理由&#xff0c;但此类论文的数量并不是很多&#xff0c;语义分割的多数方法还是使用深度学习直接做像素分类。在对比两者…

【Unity】如何做一个很平滑的行人动画,且可以根据行人速度动态调整动画速度?

首先我们定一下不同速度对应的行人动作状态&#xff0c;设计为四种状态&#xff1a; 静止站立Stand&#xff1a;0~maxStandSpeed走路Walk&#xff1a;minWalkSpeed~maxWalkSpeed慢跑Jog&#xff1a;minJogSpeed~maxJogSpeed快跑Run&#xff1a;大于MinRunSpeed 我们可以使用A…

FISCO BCOS x GitLink,为国产开源技术生态注入新活力

作为中国领先的区块链底层平台之一&#xff0c;FISCO BCOS 自成立以来始终致力于推动国产开源区块链技术的应用和普及。近期&#xff0c;FISCO BCOS 将开源代码托管到CCF官方代码托管平台 GitLink &#xff08;确实开源&#xff09;&#xff0c;为国产开源技术生态注入新活力。…

C++类型转换深度解析:从基础数据类型到字符串,再到基础数据类型的完美转换指南

前言 在 C 编程中&#xff0c;我们经常需要在基础数据类型&#xff08;如 int、double、float、long、unsigned int 等&#xff09;与 string 类型之间进行转换。这种转换对于处理用户输入、格式化输出、数据存储等场景至关重要。 本文将详细介绍如何在 C 中实现这些转换。 文…

刚实习的大学生如何避免招聘骗局?

大学生在求职过程中&#xff0c;常常成为招聘骗局的受害者。为了避免这种情况&#xff0c;大学生需要提高警惕&#xff0c;采取一系列措施来防范招聘骗局。以下是一些建议&#xff1a; 首先&#xff0c;大学生应当保持警惕&#xff0c;不轻信招聘信息。在求职时&#xff0c;务…

使用 Elasticsearch 设计大规模向量搜索

作者&#xff1a;Jim Ferenczi 第 1 部分&#xff1a;高保真密集向量搜索 简介 在设计向量搜索体验时&#xff0c;可用选项的数量之多可能会让人感到不知所措。最初&#xff0c;管理少量向量很简单&#xff0c;但随着应用程序的扩展&#xff0c;这很快就会成为瓶颈。 在本系列…

Linux下的/etc/resolv.conf

Linux下的/etc/resolv.conf 文件用于配置域名解析器的设置&#xff0c;告诉系统在解析域名时要查询哪些DNS服务器。nameserver&#xff1a;指定DNS服务器的IP地址。你可以列出多个nameserver&#xff0c;系统将按顺序尝试它们&#xff0c;直到找到可用的DNS服务器。 nameserve…

ip地址公和内有什么区别

在数字化世界中&#xff0c;IP地址扮演着至关重要的角色。它不仅是网络设备的身份标识&#xff0c;更是信息传输的桥梁。然而&#xff0c;并非所有IP地址都拥有相同的属性和功能。公有IP地址和私有IP地址&#xff0c;作为IP地址的两大类别&#xff0c;它们存在着显著的差异。虎…

C#A类调用B类的方法,在方法中更新B类的控件

1.首先在B类中定义静态成员 public static B bnull; 其次&#xff0c;在B类构造函数中给静态成员初始化 public B(){B this;InitializeComponent();} 在A类中&#xff0c;调用更新B类控件的方法 B.b.Method("已通过"); 2.如果当前方法所在的线程不是UI线程&…

成都百洲文化传媒有限公司电商服务的领航者

在当今数字化浪潮席卷全球的时代&#xff0c;电商行业以其独特的魅力和无穷的潜力&#xff0c;正成为推动经济发展的重要引擎。在这一领域&#xff0c;成都百洲文化传媒有限公司以其专业的电商服务和创新的营销理念&#xff0c;成为了行业的佼佼者&#xff0c;引领着电商服务的…

芯片后端对于芯片设计公司的重要性

在芯片设计流程中&#xff0c;后端设计是一个至关重要的环节&#xff0c;它直接关系到芯片从设计到实际生产的转化&#xff0c;以及最终产品的性能、可靠性、成本和上市时间。 以下是为什么芯片后端非常重要的几个关键原因&#xff1a; 物理实现&#xff1a;后端设计是芯片从逻…