当前位置: 首页 > news >正文

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

假期归来继续刷题,图论第二天,主要是进一步熟悉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 + inext_y = y + jif next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):continueif not visited[next_x][next_y] and grid[next_x][next_y] == 1:visited[next_x][next_y] = Truedfs(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 = 0for i in range(n):for j in range(m):# 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。if grid[i][j] == 1 and not visited[i][j]:res += 1visited[i][j] = Truedfs(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:returnvisited[x][y] = Truefor i, j in direction:next_x = x + inext_y = y + jif next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):continuedfs(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 = 0for i in range(n):for j in range(m):# 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。if grid[i][j] == 1 and not visited[i][j]:res += 1dfs(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] = Truewhile que:cur_x, cur_y = que.popleft()for i, j in directions:next_x = cur_x + inext_y = cur_y + jif next_y < 0 or next_x < 0 or next_x >= len(grid) or next_y >= len(grid[0]):continueif not visited[next_x][next_y] and grid[next_x][next_y] == 1: visited[next_x][next_y] = Trueque.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 = 0for i in range(n):for j in range(m):if grid[i][j] == 1 and not visited[i][j]:res += 1bfs(grid, visited, i, j)print(res)

相关文章:

  • 养生融入生活,畅享健康人生
  • MySQL8查询某个JSON类型的字段中出现过的所有键名(json key name)并去重返回
  • conda虚拟环境相关操作
  • 第三章:langchain加载word文档构建RAG检索教程(基于FAISS库为例)
  • Spring Boot项目集成Aviator实现成本计算模块
  • 【阿里云大模型高级工程师ACP习题集】3 总结与展望
  • vscode远程服务器连接----过程尝试写入的管道不存在
  • 修改MySQL枚举类型添加‘location‘值
  • 【AI】Ubuntu 22.04 evalscope 模型评测 Qwen3-4B-FP8
  • Linux——https基础理论
  • 【AI论文】FormalMATH:大型语言模型形式化数学推理能力基准测试
  • C语言内存函数及大小端字节序!
  • Mysql order by 用法
  • Vue + Element UI 表单弹窗输入法卡顿问题解决方案
  • 用 Tailwind CSS 优化你的 Vue 3 项目! ! !
  • 计算机硬件:AMD X670E与B650主板的PCIe通道分配
  • 在 Laravel 12 中实现 WebSocket 通信时进行身份验证
  • 水质监控预警管理平台
  • 构建 Web 浏览 AI Agent:Pydantic + MCP 实现指南
  • C#学习第21天:安全与加密(Security and Cryptography)
  • 解读|降准叠加政策利率、公积金贷款利率、结构性政策工具利率全线下调,影响有多大?
  • 水中托举救出落水孩童后遇难,42岁退役军人高武被确认为见义勇为
  • 抗战回望20︱《山西省战区抗敌行政工作检讨会议议决案》:“强民政治”、“说服行政”
  • 五一假期上海边检查验出入境人员超61万人次,同比增长23%
  • 强沙尘暴压城近万名游客被困,敦煌如何用3小时跑赢12级狂风?
  • 工程机械行业景气度持续回升,三大龙头一季度营收、净利双增