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

BFS解决最短路径问题

注意:用队列进行BFS 求解最短路径时,需要按 “层” 处理节点 —— 同一层的所有节点属于 “同一步”,需一次性次性处理完当前层的所有节点后,再进入下一层。与floodfill算法区别在于最短路径问题需要记录层数(步数),而 Flood Fill 更关注是否遍历完所有连通节点。

一. (1926.) 迷宫中离入口最近的出口

在这里插入图片描述
利⽤层序遍历来解决迷宫问题,是最经典的做法。
我们可以从起点开始层序遍历,并且在遍历的过程中记录当前遍历的层数,并且标记已经遍历过的位置,避免重复计算。这样就能在找到出⼝的时候,得到起点到出⼝的最短距离

class Solution {typedef pair<int,int> pir;int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};bool v[100][100];//用于标记每一位状态是否遍历过,定义全局变量会自动初始化为0
public:int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {int ret=0;//记录最短路径queue<pir> q;//辅助宽搜int m=maze.size(),n=maze[0].size();q.push({entrance[0],entrance[1]});v[entrance[0]][entrance[1]]=true;while(q.size()){ret++;int sz=q.size();for(int j=0;j<sz;j++)//每次都要把队列中的元素删除完,这样算走一步,与floodfill算法中依次遍历并删除不同{auto[a,b]=q.front();q.pop(); for(int i=0;i<4;i++){int x=a+dx[i],y=b+dy[i];if(x>=0&&x<m&&y>=0&&y<n&&maze[x][y]=='.'&&!v[x][y]){if(x==0||x==m-1||y==0||y==n-1) //判断是否到达边界即出口{return ret;}q.push({x,y});v[x][y]=true;}}    }}return -1;}
};

二. (433.) 最小基因变化

在这里插入图片描述
如果将每次字符串的变换抽象成图中的两个顶点和⼀条边的话,问题就变成了边权为 1的最短路问题。因此,从起始的字符串开始,来⼀次 bfs 即可。

class Solution {char d[4]={'A','C','G','T'};
public:int minMutation(string startGene, string endGene, vector<string>& bank) {unordered_set<string> bk;//预处理基因库unordered_set<string> v;//标记是否遍历过//预处理for(auto s:bank){bk.insert(s);}//处理边界情况queue<string> q;v.insert(startGene);q.push(startGene); int ret=0;//bfswhile(q.size()){ret++;int sz=q.size();while(sz--){auto s=q.front();v.insert(s);q.pop();for(int i=0;i<8;i++)//遍历字符串中每一位{string tmp=s;//避免原字符串被修改for(int j=0;j<4;j++)//遍历每一位发生基因变化可能的情况{tmp[i]=d[j];if(bk.count(tmp)&&!v.count(tmp)){if(tmp==endGene) return ret;//条件满足直接返回q.push(tmp);v.insert(tmp);}}}}}return -1;}
}; 

三.(127.) 单词接龙

在这里插入图片描述
思路与二相同,转化为bfs的最短路径问题

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string> hash(wordList.begin(),wordList.end());unordered_set<string> v;//判断单词是否被遍历//处理边界情况if(!hash.count(endWord)) return 0;queue<string> q;q.push(beginWord);int ret=1;while(q.size())//进行bfs{ret++;int sz=q.size();while(sz--)//遍历每一层元素{auto s=q.front();v.insert(s);q.pop();for(int k=0;k<s.size();k++)//遍历单词每一位的变化{string tmp=s;for(char i='a';i<='z';i++)//单词每一位变化的情况{tmp[k]=i;if(hash.count(tmp)&&!v.count(tmp)){if(tmp==endWord) return ret;//符合条件直接退出q.push(tmp);v.insert(tmp);}}}}}return 0;}
};

四. (675.) 为高尔夫比赛砍树

在这里插入图片描述
1.先找出砍树的顺序;
2. 然后按照砍树的顺序,⼀个⼀个的⽤ bfs 求出最短路即可

class Solution {int m, n;int dx[4] = {0, 0, -1, 1};int dy[4] = {1, -1, 0, 0};bool vis[50][50];public:int cutOffTree(vector<vector<int>>& f) {m = f.size(), n = f[0].size();vector<pair<int, int>> v;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (f[i][j] > 1)v.push_back({i, j});//将可以砍的树入队列// 找出砍树的顺序sort(v.begin(), v.end(),[&](const pair<int, int>& p1, const pair<int, int>& p2) {return f[p1.first][p1.second] < f[p2.first][p2.second];});// 按顺序砍树int ba = 0, bb = 0;//初始位置int ret = 0;for (auto& [a, b] : v) {int r = bfs(f, ba, bb, a, b);if (r == -1)return -1;ret += r;ba = a, bb = b;//更新初始位置}return ret;}int bfs(vector<vector<int>>& f, int bx, int by, int ex, int ey) {if (bx == ex && by == ey) return 0;memset(vis, 0, sizeof(vis)); // 会重复调用bfs所以每次要清零queue<pair<int, int>> q;q.push({bx, by});int ret = 0;//记录步数while (q.size()) {ret++;int sz = q.size();//记录层数,每一层中都只算一步while (sz--) {auto [a, b] = q.front();q.pop();vis[a][b] = true;for (int i = 0; i < 4; i++) {//遍历每一步可能的方向int x = a + dx[i], y = b + dy[i];if (x >= 0 && x < m && y >= 0 && y < n && f[x][y] >= 1 &&!vis[x][y]) {//if(f[x][y]==f[ex][ey]) return ret;if (x == ex && y == ey) return ret;q.push({x, y});vis[x][y] = true;}}}}return -1;}
};
http://www.dtcms.com/a/466464.html

相关文章:

  • DNS 隐私防护与用户画像防范策略
  • 免费的x网站域名上海十大工业设计公司
  • 如何在Android Studio中使用Gemini进行AI Coding
  • 学校网站建设材料惠州抖音推广
  • DIN70121协议解读
  • 网站优化软件常用python编程软件
  • 软件的设计原理
  • petri网学习笔记——(五)第二章 petri网的动态性质
  • 长兴网站制作公司wordpress tag优化
  • Spring Bean 生命周期详解:初始化与销毁方式对比与实践
  • 做交易网站什么开发语言网络工程师
  • DeviceNet 转 Modbus TCP 协议转换在 S7-1200 PLC化工反应釜中的应用
  • 网站建设公司网络服务学美工难吗
  • S29-昆仑触屏串口批量写应用
  • C# 委托(Delegate)
  • 企业单位网站建设内容需要什么saas电商建站系统
  • 【63】OpenCV C++实战篇——用C++实现的直线卡尺工具--自选找线方向(从左到右、从右到左、从上到下、从下到上)
  • 做网站你们用什么浏览器如何免费建立个人网站
  • 《金钱心理学》读后感
  • 临沂网站设计建设wordpress 下拉菜单设置
  • PyTorch Transformers| Azure
  • 2.c++面向对象(二)
  • 苍穹外卖-Apache ECharts与数据统计
  • 合肥企业建站系统wap网站浏览器
  • python进阶_Day4
  • 网站开发小图标大全wordpress显示当前位置
  • 江苏建设信息网站有时候打不开网站建设客户问题
  • .Net Core WebApi集成Swagger
  • 趣味学网工:IPv6是连接未来的数字基石(IPv6的技术地位、重要作用、市场行情、应用场景等)
  • Linux 基本入门