代码随想录算法训练营第五十六天| 图论2—卡码网99. 岛屿数量(dfs bfs)

news2025/5/13 21:52:56

假期归来继续刷题,图论第二天,主要是进一步熟悉dfs 和 bfs 的运用。

99. 岛屿数量(dfs)

99. 岛屿数量

ACM模式还是需要练,不过现在输入输出的感觉已经比较熟悉了。首先是要按照输入搭建一个grid,然后有一个对应的全是False 的 visit。

关于方向就只有上下左右四个,如果可以走斜向,方向就变成八个了。递归的过程其实比较好理解,就是当前x,y逐步相加,如果越界了就continue,然后如果碰到了grid中为1但没有visit的,就变成visit继续向后递归,当四边都没法符合判断条件的话就进行返回,这就是dfs顺着一条路走下去的思想。

然后是主函数中的调用,当碰到第一个符合条件的地块开始,并计数,记得同时将这块变为True,因为dfs函数里直接是从下一个地块开始转换的。然后不停递归,当结束的时候,就继续回到主函数的遍历中,去测下一个符合if grid[i][j] == 1 and not visited[i][j]:条件的地块,当碰到就是第二块岛,记得将数量+1然后继续递归。

简单理解,主函数中,i,j二次遍历,一旦找到一个为1的地块便计数+1,同时dfs开始,当dfs遍历完之后,i,j继续遍历,这时候如果遍历到之前dfs遍历的地块,也会因为visit中为True而不会开始dfs。可以想象成发现一个起点,dfs开始逐步扩散发掘所有连着的地块。

# dfs方法一
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] 

def dfs(grid, visited, x, y):
    for i, j in direction:
        next_x = x + i
        next_y = y + j
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
            visited[next_x][next_y] = True
            dfs(grid, visited, next_x, next_y)


if __name__ == '__main__':  
    n, m = map(int, input().split())
    
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    
    visited = [[False] * m for _ in range(n)]
    
    res = 0
    for i in range(n):
        for j in range(m):
            # 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。
            if grid[i][j] == 1 and not visited[i][j]:
                res += 1
                visited[i][j] = True
                dfs(grid, visited, i, j)
    
    print(res)

dfs的版本二,变化不大,总体方法更符合之前回溯的模板,即参数-终止条件-单层逻辑。

版本一的写法是 :下一个节点是否能合法已经判断完了,传进dfs函数的就是合法节点。

版本二的写法是:不管节点是否合法,上来就dfs,然后在终止条件的地方进行判断,不合法再return。

理论上来讲,版本一的效率更高一些,因为避免了 没有意义的递归调用,在调用dfs之前,就做合法性判断。 但从写法来说,可能版本二 更利于理解一些。(不过其实都差不太多)

direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] 

def dfs(grid, visited, x, y):
    # 与版本一的差别,在调用前增加判断终止条件
    if visited[x][y] or grid[x][y] == 0:
        return
    visited[x][y] = True

    for i, j in direction:
        next_x = x + i
        next_y = y + j
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        dfs(grid, visited, next_x, next_y)


if __name__ == '__main__':
    # 版本二
    n, m = map(int, input().split())

    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))

    visited = [[False] * m for _ in range(n)]

    res = 0
    for i in range(n):
        for j in range(m):
            # 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。
            if grid[i][j] == 1 and not visited[i][j]:
                res += 1
                dfs(grid, visited, i, j)

    print(res)

99. 岛屿数量(bfs)

深搜是一条路走到头,广搜则是一圈一圈的扩散,可以类比为二叉树的层序遍历,原本是每个节点有左右两个子节点,现在变成每个地块有上下左右四个地块。

在bfs函数里,记住每开始一次bfs,要重置一次que,然后将当前的地块x,y 加入队列,并在visit中变成True。之后便是弹出,符合条件加入,重复直到队列为空。

之后主函数调用则是一样的思路,类似发现一个起点,然后一圈一圈开始扩散,直到无法扩散,便开始遍历寻找下一个岛屿的起点。

from collections import deque
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
def bfs(grid, visited, x, y):
    que = deque([])
    que.append([x,y])
    visited[x][y] = True
    while que:
        cur_x, cur_y = que.popleft()
        for i, j in directions:
            next_x = cur_x + i
            next_y = cur_y + j
            if next_y < 0 or next_x < 0 or next_x >= len(grid) or next_y >= len(grid[0]):
                continue
            if not visited[next_x][next_y] and grid[next_x][next_y] == 1: 
                visited[next_x][next_y] = True
                que.append([next_x, next_y])
 
 
if __name__ == "__main__":
    n, m = map(int, input().split())
    grid = []
    for i in range(n):
        grid.append(list(map(int, input().split())))
    visited = [[False] * m for _ in range(n)]
    res = 0
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 1 and not visited[i][j]:
                res += 1
                bfs(grid, visited, i, j)
    print(res)
 

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

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

相关文章

基于Django框架的股票分红数据爬虫和展示系统

项目截图 一、项目简介 本项目是一个基于 Django 框架的股票分红数据爬虫和展示系统。它可以从东方财富网站爬取股票分红数据&#xff0c;并将数据存储到 Django 数据库中&#xff0c;同时提供数据查询、导出和图表展示功能。该系统为用户提供了一个方便的平台&#xff0c;用于…

QT高级(1)QTableView自定义委托集合,一个类实现若干委托

自定义委托集合 1同系列文章2 功能3 源码 1同系列文章 QT中级&#xff08;1&#xff09;QTableView自定义委托&#xff08;一&#xff09;实现QSpinBox、QDoubleSpinBox委托 QT中级&#xff08;2&#xff09;QTableView自定义委托&#xff08;二&#xff09;实现QProgressBar委…

小芯片大战略:Chiplet技术如何重构全球半导体竞争格局?

在科技飞速发展的今天&#xff0c;半导体行业作为信息技术的核心领域之一&#xff0c;其发展速度和创新水平对全球经济的发展具有举足轻重的影响。然而&#xff0c;随着芯片制造工艺的不断进步&#xff0c;传统的单片集成方式逐渐遇到了技术瓶颈&#xff0c;如摩尔定律逐渐逼近…

普通IT的股票交易成长史--股价起伏的真相-缺口(2)

声明&#xff1a;本文章的内容只是自己学习的总结&#xff0c;不构成投资建议。价格行为理论学习可参考简介中的几位&#xff0c;感谢他们的无私奉献。 送给自己的话&#xff1a; 仓位就是生命&#xff0c;绝对不能满仓&#xff01;&#xff01;&#xff01;&#xff01;&…

MindSpore框架学习项目-ResNet药物分类-模型优化

目录 5.模型优化 5.1模型优化 6.结语 参考内容&#xff1a; 昇思MindSpore | 全场景AI框架 | 昇思MindSpore社区官网 华为自研的国产AI框架&#xff0c;训推一体&#xff0c;支持动态图、静态图&#xff0c;全场景适用&#xff0c;有着不错的生态 本项目可以在华为云modelar…

Kubernetes(k8s)学习笔记(八)--KubeSphere定制化安装

1执行下面的命令修改上一篇中yaml文件来实现定制化安装devops kubectl edit cm -n kubesphere-system ks-installer 主要是将devops几个配置由False改为True 然后使用下面的命令查看安装日志 kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l …

养生:为健康生活筑牢根基

养生并非遥不可及的目标&#xff0c;而是贯穿于日常生活的点滴之中。从饮食、运动到心态调节&#xff0c;每一个环节都对我们的健康有着重要意义。以下为你详细介绍养生的实用策略&#xff0c;助力你开启健康生活模式。 饮食养生&#xff1a;科学搭配&#xff0c;滋养生命 合…

Linux510 ssh服务 ssh连接

arning: Permanently added ‘11.1.1.100’ (ECDSA) to the list of known hosts. rooot11.1.1.100’s password: Permission denied, please try again. rooot11.1.1.100’s password: Permission denied, please try again 还没生效 登不上了 失效了 sshcaozx26成功登录 …

关键点检测--使用YOLOv8对Leeds Sports Pose(LSP)关键点检测

目录 1. Leeds Sports Pose数据集下载2. 数据集处理2.1 获取标签2.2 将图像文件和标签文件处理成YOLO能使用的格式 3. 用YOLOv8进行训练3.1 训练3.2 预测 1. Leeds Sports Pose数据集下载 从kaggle官网下载这个数据集&#xff0c;地址为link&#xff0c;下载好的数据集文件如下…

独立按键控制LED

目录 1.独立按键介绍 2.原理图 3.C51数据运输 解释&#xff1a;<< >> ​编辑 解释&#xff1a;& | 解释&#xff1a;^ ~ ​编辑 4.C51基本语句 5.按键的跳动 6.独立按键控制LED亮灭代码 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1…

计算机科技笔记: 容错计算机设计03 系统可信性的度量 偶发故障期 浴盆曲线 韦布尔分布

可靠性 简化表达式 偶发故障期&#xff0c;系统发生故障概率趋近于一个常数 浴盆曲线 MTTF和计算 韦布尔分布 马尔可夫链 可靠度

爬虫准备前工作

1.Pycham的下载 网址&#xff1a;PyCharm: The only Python IDE you need 2.Python的下载 网址&#xff1a;python.org&#xff08;python3.9版本之后都可以&#xff09; 3.node.js的下载 网址&#xff1a;Node.js — 在任何地方运行 JavaScript&#xff08;版本使用18就可…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】7.1 主流可视化工具对比(Tableau/Matplotlib/Python库)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 第七章 可视化工具集成&#xff1a;Tableau、Matplotlib与Python库深度对比7.1 主流可视化工具对比&#xff1a;技术选型的决策框架7.1.1 工具定位与核心能力矩阵7.1.2 数据…

操作系统实验习题解析 上篇

孤村落日残霞&#xff0c;轻烟老树寒鸦&#xff0c;一点飞鸿影下。 青山绿水&#xff0c;白草红叶黄花。 ————《天净沙秋》 白朴 【元】 目录 实验一&#xff1a; 代码&#xff1a; 解析&#xff1a; 运行结果&#xff1a; 实验二&#xff1a; 代码解析 1. 类设计 …

基于Arduino Nano的DIY示波器

基于Arduino Nano的DIY示波器&#xff1a;打造属于你的口袋实验室 前言 在电子爱好者的世界里&#xff0c;示波器是不可或缺的工具之一。它能够帮助我们观察和分析各种电子信号的波形&#xff0c;从而更好地理解和调试电路。然而&#xff0c;市面上的示波器价格往往较高&…

渠道销售简历模板范文

模板信息 简历范文名称&#xff1a;渠道销售简历模板范文&#xff0c;所属行业&#xff1a;其他 | 职位&#xff0c;模板编号&#xff1a;KRZ3J3 专业的个人简历模板&#xff0c;逻辑清晰&#xff0c;排版简洁美观&#xff0c;让你的个人简历显得更专业&#xff0c;找到好工作…

JAVA练习题(1) 卖飞机票

import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);System.out.println("请输入飞机的票价&#xff1a;");int pricesc.nextInt();System.out.println("请输入月份&#xff1a;");…

杆件的拉伸与压缩变形

杆件的拉伸与压缩 第一题 Q u e s t i o n \mathcal{Question} Question 图示拉杆沿斜截面 m − m m-m m−m由两部分胶合而成。设在胶合面上许用拉应力 [ σ ] 100 MPa [\sigma]100\text{MPa} [σ]100MPa&#xff0c;许用切应力 [ τ ] 50 MPa [\tau]50\text{MPa} [τ]50MP…

企业开发平台大变革:AI 代理 + 平台工程重构数字化转型路径

在企业数字化转型的浪潮中&#xff0c;开发平台正经历着前所未有的技术革命。从 AST&#xff08;抽象语法树&#xff09;到 AI 驱动的智能开发&#xff0c;从微服务架构到信创适配&#xff0c;这场变革不仅重塑了软件开发的底层逻辑&#xff0c;更催生了全新的生产力范式。本文…

《汽车噪声控制》复习重点

题型 选择 填空 分析 计算 第一章 噪声定义 不需要的声音&#xff0c;妨碍正常工作、学习、生活&#xff0c;危害身体健康的声音&#xff0c;统称为噪声 噪声污染 与大气污染、水污染并称现代社会三大公害 声波基本概念 定义 媒质质点的机械振动由近及远传播&am…