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

网格图之bfs

网格图的基本概念

 以1210. 穿过迷宫的最少移动次数 - 力扣(LeetCode)的图为例子,这个就是网格图

一、BFS在网格图中的核心特性

1. 遍历特性

  • 层级扩展:从起点开始逐层向外扩展,先访问所有距离为1的节点,再距离为2的节点,依此类推

  • 队列实现:使用队列(queue)数据结构实现"先进先出"的访问顺序

  • 最短路径保证:在无权网格中,首次访问某节点时的路径必然是最短路径

2. 网格适应特点

  • 方向处理:通常处理4方向(上下左右)或8方向(含对角线)移动

  • 坐标表示:用(row,col)二元组表示网格位置

  • 边界检查:移动时需检查是否越出网格边界

二、BFS在网格图中的基本实现模版

标准实现模板

int bfs(vector<vector<char>>& grid, pair<int,int> start) {int m = grid.size(), n = grid[0].size();queue<pair<int,int>> q;vector<vector<int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // 4方向移动// 初始化q.push(start);grid[start.first][start.second] = '0'; // 标记已访问int steps = 0;while(!q.empty()) {int size = q.size();for(int i = 0; i < size; i++) { // 处理当前层级所有节点auto [r,c] = q.front(); q.pop();// 处理当前节点...for(auto& dir : dirs) { // 探索相邻节点int nr = r + dir[0], nc = c + dir[1];if(nr >=0 && nr < m && nc >=0 && nc < n && grid[nr][nc] == '1') {q.push({nr,nc});grid[nr][nc] = '0'; // 标记已访问}}}steps++; // 完成一层遍历}return steps;
}

关键组件说明

  1. 队列(queue):存储待访问节点

  2. 方向数组(dirs):定义移动方向

  3. 层级控制:通过size = q.size()实现层级遍历

  4. 访问标记:直接修改原网格或使用独立visited数组

三、BFS在网格图中的典型应用

1. 最短路径问题

特点

  • 天然适合求解无权网格中的最短路径

  • 时间复杂度O(mn),空间复杂度O(mn)

示例场景

  • 迷宫最短路径

  • 骑士最短移动步数(象棋马走日)

2. 层级扩展问题

特点

  • 明确知道当前处理的是第几层/第几步

  • 可以限制扩展深度

示例场景

  • 病毒传播模拟

  • 火灾蔓延预测

  • 社交网络中的n度好友

3. 多源点问题

特点

  • 同时从多个起点开始BFS

  • 适用于"最近X距离"类问题

示例场景

  • 每个海洋区域到最近陆地的距离(LeetCode 542)

  • 多出发点的最短路径

五、BFS在网格图中的优化技巧

1. 双向BFS

适用场景

  • 起点和终点都已知的情况

  • 大幅减少搜索空间

实现要点

  • 同时从起点和终点开始BFS

  • 当两边的搜索相遇时终止

2. A*搜索

适用场景

  • 有权网格或需要启发式引导的情况

  • 结合了BFS和启发式估计

3. 层级剪枝

技巧

  • 提前知道最大有效距离时可提前终止

  • 某些问题不需要完整遍历整个网格

六、经典问题示例

1. 岛屿数量问题(BFS版)

cpp

复制

下载

int numIslands(vector<vector<char>>& grid) {if(grid.empty()) return 0;int m = grid.size(), n = grid[0].size();vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};int islands = 0;for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {if(grid[i][j] == '1') {islands++;queue<pair<int,int>> q;q.push({i,j});grid[i][j] = '0';while(!q.empty()) {auto [r,c] = q.front(); q.pop();for(auto& dir : dirs) {int nr = r + dir.first, nc = c + dir.second;if(nr >=0 && nr < m && nc >=0 && nc < n && grid[nr][nc] == '1') {q.push({nr,nc});grid[nr][nc] = '0';}}}}}}return islands;
}

2. 矩阵中的最短路径

cpp

复制

下载

int shortestPathBinaryMatrix(vector<vector<int>>& grid) {if(grid[0][0] == 1) return -1;int n = grid.size();vector<vector<int>> dirs = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};queue<pair<int,int>> q;q.push({0,0});grid[0][0] = 1; // 标记为已访问并用值记录步数while(!q.empty()) {auto [r,c] = q.front(); q.pop();if(r == n-1 && c == n-1) return grid[r][c];for(auto& dir : dirs) {int nr = r + dir[0], nc = c + dir[1];if(nr >=0 && nr <n && nc >=0 && nc <n && grid[nr][nc] == 0) {grid[nr][nc] = grid[r][c] + 1;q.push({nr,nc});}}}return -1;
}

七、实际应用场景

  1. 游戏开发

    • 实时战略游戏中的单位寻路

    • 塔防游戏中的敌人移动路径

    • 解谜游戏中的最少步数计算

  2. 机器人导航

    • 清洁机器人的全覆盖路径规划

    • 仓储机器人的货架间导航

    • 无人机避障路径规划

  3. 图像处理

    • 连通区域分析

    • 图像分割中的区域生长

    • 像素级操作的范围控制

BFS在网格图中的这些特性使其成为解决空间搜索问题的强大工具,特别是在需要最短路径或层级信息的场景下表现出色。理解这些基本特性是有效应用BFS解决复杂问题的基础。

参考资源

分享丨【算法题单】网格图(DFS/BFS/综合应用)- 讨论 - 力扣(LeetCode)

http://www.xdnf.cn/news/5731.html

相关文章:

  • 水平翻转 垂直翻转 颜色处理
  • 二、HAL库的命名规则详解
  • 【Python】Python 单例模式 8 大核心应用场景深度解析(2025 新版)
  • 前端vue+elementplus实现上传通用组件
  • 非结构化数据的智能化蜕变:从混沌到知识的进化之路
  • Python教程(四)参数提取pymysql
  • 直方图详解
  • Python | Dashboard制作 【待续】
  • 1.3.3 tinyalsa详细介绍
  • 14.three官方示例+编辑器+AI快速学习webgl_buffergeometry_instancing_interleaved
  • 【语法】C++的多态
  • 专题二:二叉树的深度优先搜索
  • AI+Java开发项目——石头迷阵游戏
  • M0基础篇之DAC
  • LAN-402 全国产信号采集处理模块K7-325T(4通道采集)
  • LC滤波器与电感、电容的区别:技术分析与应用
  • springboot做junit单元测试详细步骤
  • 深入理解 iOS 开发中的 `use_frameworks!`
  • 大数据课设——基于电影数据集,分析导演影响力,绘制各种可视化图表
  • 【Linux】Linux内核的网络协议之socket理解
  • 丝杆升降机限位开关信号机制剖析与工程实践:从原理到 PLC 控制全流程解析
  • 监控易运维管理软件:架构稳健,组件强大
  • 使用 OAuth 2.0 保护 REST API
  • fetch post请求SSE「eventsource-parser/stream」
  • 网络基础知识梳理和Muduo库使用
  • 5月12日复盘-RNN
  • python打卡day23@浙大疏锦行
  • 【数据结构】双链表
  • 关于读写锁的一些理解
  • C++的构造函数和析构函数