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

算法第五十一天:图论part02(第十一章)

1.岛屿数量

99. 岛屿数量

🌟 思路总结 — DFS 版

1️⃣ 问题本质

  • 给定一个二维矩阵 grid,1 表示陆地,0 表示水

  • 统计岛屿数量,每个岛屿由上下左右相邻的陆地组成

本质是 在二维网格中找连通块 的问题。


2️⃣ 核心思路

  1. 遍历矩阵

    • 对每个格子 (i,j)

      • 如果是陆地 (grid[i][j] == 1) 且未访问过
        → 说明发现一个新岛屿,岛屿计数 +1

  2. DFS 扩展岛屿

    • 从新发现的陆地出发,深度优先递归访问上下左右相邻的陆地

    • 每访问一个陆地就标记为已访问 visited[i][j] = True

    • 递归结束后,这块岛屿的所有陆地都被标记,避免重复计数

  3. 返回岛屿数量

    • 遍历完矩阵后,岛屿计数就是答案


3️⃣ 核心技巧

  1. 方向数组

 

direction = [[0,1],[1,0],[0,-1],[-1,0]] # 右、下、左、上

  • 遍历邻居时统一处理

  • next_x = x + dx, next_y = y + dy

  1. 访问标记

  • visited 二维布尔数组标记已访问的陆地

  • DFS 或 BFS 入队/递归时立即标记,防止重复访问

  1. 越界判断

 

if nextx < 0 or nextx >= n or nexty < 0 or nexty >= m: continue

  • 避免访问矩阵外的元素

#深度优先
direction = [[0, 1], [1, 0], [-1, 0], [0, -1]]  #依次是右,下, 上, 左
def dfs(grid, visited, x, y):for i, j in direction:nextx = x + inexty = y + j#判断是否越界if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continue# 如果是陆地且未访问if grid[nextx][nexty] == 1 and visited[nextx][nexty] == False:visited[nextx][nexty] = Truedfs(grid, visited, nextx, nexty)def 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)]result = 0for i in range(n):for j in range(m):if grid[i][j] == 1 and visited[i][j] == False:result += 1visited[i][j] = True#dfsdfs(grid, visited, i, j)return resultif __name__ == "__main__":print(main())

2.广度优先搜索的理论基础

步骤:先将起点加入队列, 标记为true, 取出当前节点,沿四个方向遍历判断是否访问过,未访问则加入队列,标记为true。直至队列为空则广搜结束

direction = [[0,1], [1, 0], [-1, 0], [0, -1]]def bfs(grid, visited, x, y):que = deque()que.apppend(x, y)visited[x][y] == Truewhile que:curx, cury = que.popleft()for i, j in direction:nextx = curx + inexty = cury + jif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continueif not visited[nextx][nexty]:que.append([nextx, nexty])visited[nextx][nexty] == 1

岛屿数量用广度搜索重做一遍:


from collections import dequedirection = [[0, 1], [1, 0], [-1, 0], [0, -1]]
def bfs(grid, visited, x, y):queue = deque()queue.append([x, y])visited[x][y] = Truewhile queue:cur_x, cur_y = queue.popleft()  #取出队首元素for i, j in direction:nextx = cur_x + inexty = cur_y + jif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continueif not visited[nextx][nexty] and grid[nextx][nexty] == 1:visited[nextx][nexty] = Truequeue.append([nextx, nexty])def 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)]result = 0for i in range(n):for j in range(m):if grid[i][j] == 1 and not visited[i][j]:result += 1bfs(grid, visited, i, j)print(result)if __name__ == "__main__":main()

3.岛屿的最大面积

📝 代码功能

  • 这是一个求最大岛屿面积的程序(不是岛屿数量)。

  • 输入一个 n×m 的矩阵 grid1 表示陆地,0 表示水。

  • 使用 DFS(深度优先搜索)遍历每一块岛屿,同时统计它的面积。

  • 最终输出所有岛屿中的最大面积


🔑 核心思路

  1. 方向数组

     

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

    用来表示四个相邻方向:右、下、上、左。

  2. DFS 深度优先搜索

     

    def dfs(grid, visited, x, y): global area for i, j in direction: nextx = x + i nexty = y + j ...

    • 从一个陆地 (x, y) 出发,递归探索它相邻的陆地;

    • 每发现一个新的陆地,就 area += 1

    • 并且标记 visited[nextx][nexty] = True,避免重复访问。

  3. 遍历矩阵

     

    for i in range(n): for j in range(m): if grid[i][j] == 1 and not visited[i][j]: area = 1 visited[i][j] = True dfs(grid, visited, i, j) res = max(res, area)

    • 遍历整个矩阵;

    • 每遇到一个未访问的陆地 (i, j),说明发现一块新岛屿;

    • 从这里开始 DFS,计算该岛屿面积;

    • 更新最大面积 res

direction = [[0, 1], [1, 0], [-1, 0], [0, -1]]
area = 0
def dfs(grid, visited, x, y):global areafor i, j in direction:nextx = x + inexty = y + jif nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):continueif not visited[nextx][nexty] and grid[nextx][nexty] == 1:area += 1visited[nextx][nexty] = Truedfs(grid, visited, nextx, nexty)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]:area = 1visited[i][j] = Truedfs(grid, visited, i, j)res = max(res, area)
print(res)

今日结束啦!!!

http://www.lryc.cn/news/625649.html

相关文章:

  • AI驱动的SEO关键词优化秘籍
  • 【LeetCode题解】LeetCode 162. 寻找峰值
  • SQL 语句进阶实战:从基础查询到性能优化全指南
  • Docker+Nginx+Node.js实战教程:从零搭建高可用的前后端分离项目
  • 黑客哲学之学习笔记系列(六)
  • Node.js完整安装配置指南(包含国内镜像配置)
  • HTB 赛季8靶场 - CodeTwo
  • HarmonyOS 实战:学会在鸿蒙中使用第三方 JavaScript 库(附完整 Demo)
  • 土地财政历史探寻
  • 陪诊系统开发哪家强?XK+支持 API对接+私有化部署,按需定制功能模块!
  • 涡流-信号完整性分析
  • 软件开发中的 8 个伦理问题示例
  • KMM跨平台叛逃实录:SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架(代码复用率85%)
  • MySQL事务篇-事务概念、并发事务问题、隔离级别
  • 微软AD国产化替换倒计时——不是选择题,而是生存题
  • 【python实用小脚本-190】Python一键删除PDF任意页:输入页码秒出干净文件——再也不用在线裁剪排队
  • 《WASM驱动本地PDF与Excel预览组件的深度实践》
  • LeetCode 100 -- Day2
  • Leetcode 3654. Minimum Sum After Divisible Sum Deletions
  • C++小游戏NO.1游戏机
  • 【GNSS定位原理及算法杂记5】​​​​PPK(后处理动态定位)深度解析:后处理的艺术与 RTK 的互补
  • 【HarmonyOS】H5 实现在浏览器中正常跳转 AppLinking 至应用
  • HarmonyOS 中的 setInterval的基本使用
  • Android Coil 3拦截器Interceptor计算单次请求耗时,Kotlin
  • 进程通信:进程池的实现
  • Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
  • 【什么是非晶合金?非晶电机有什么优点?】
  • k8sday11服务发现(2/2)
  • Kubernetes 的 YAML 配置文件-kind
  • 在 Kotlin 中 使用泛型类和泛型函数