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

061.BFS 及其拓展

经典BFS

  • 的特点是逐层扩散,步长一致,从源点到目标点扩散的层数就是最短路

  • 可以是单源,也可以是多源

  • 频繁使用队列,实现形式分为 单点弹出整层弹出

  • 节点进入队列时标记状态,防止死循环

  • 压缩状态,设计转移策略

01BFS

  • 边权只有 0 和 1 ,可以看作特殊的Dijkstra

  • 使用双端队列代替优先队列 ,每次从头部弹出

  • 通过 0 更新距离的节点从头部进入双端队列

  • 通过 1 更新距离的节点从尾部进入双端队列

  • 不需要vis[]来标记状态,证明略

双向 BFS

  • 从源点,目标点同时开始

  • 每次展开节点数较小的一侧

  • 第一次出现交集返回答案

习题

01 经典BFS

leetcode 1162

class Solution {vector<int>mo={-1,0,1,0,-1};struct p{int x,y;};
public:int maxDistance(vector<vector<int>>& g) {int n=g.size();int sum=0;for(int i=0;i<n;++i){for(int j=0;j<n;++j){sum+=g[i][j];}}if(sum==0||sum==n*n){return -1;}vector<vector<bool>>vis(n,vector<bool>(n));queue<p>q;for(int i=0;i<n;++i){for(int j=0;j<n;++j){if(g[i][j]==1){q.push({i,j});}}}int ans=-1;while(q.size()){ans++;int siz=q.size();for(int i=0;i<siz;++i){auto [x,y]=q.front();q.pop();for(int i=0;i<4;++i){int nx=x+mo[i];int ny=y+mo[i+1];if(nx<0||ny<0||nx>=n||ny>=n)continue;if(vis[nx][ny]==0){vis[nx][ny]=1;q.push({nx,ny});}}}}return ans;}
};

02 设计状态转移

leetcode 691

class Solution {string get_next(string &cur,string &word){string nex="";int lc=cur.size();int lw=word.size();int i=0,j=0;while(i<lc&&j<lw){if(cur[i]==word[j]){i++;j++;}else if(cur[i]<word[j]){nex+=cur[i];i++;}else{j++;}}while(i<lc){nex+=cur[i++];}return nex;}
public:int minStickers(vector<string>& words, string t) {sort(t.begin(),t.end());vector<vector<string>>gra(26);for(string word:words){sort(word.begin(),word.end());int l=word.size();for(int i=0;i<l;++i){if(i==0||word[i]!=word[i-1]){gra[word[i]-'a'].push_back(word);}}}int ans=-1;queue<string>q;unordered_set<string>vis;vis.insert(t);q.push(t);while(q.size()){ans++;int siz=q.size();for(int i=0;i<siz;++i){string cur=q.front();q.pop();if(cur=="")return ans;for(string &word:gra[cur[0]-'a']){string nex=get_next(cur,word);if(vis.count(nex)==0){vis.insert(nex);q.push(nex);}}}}return -1;}
};

03 设计状态转移

leetcode 752

class Solution {
public:int openLock(vector<string>& deadends, string target) {if(target=="0000")return 0;unordered_set<string>vis;for(auto c:deadends){vis.insert(c);if(c=="0000")return -1;}unordered_set<string>q1;unordered_set<string>q2;q1.insert("0000");q2.insert(target);vis.insert("0000");vis.insert(target);int ans=0;while(!q1.empty()&&!q2.empty()){ans++;unordered_set<string>q3;for(const string&cur:q1){for(int i=0;i<4;++i){string n1=cur,n2=cur;int x=cur[i]-'0';char c1=((x+1)%10)+'0';char c2=((x-1+10)%10)+'0';n1[i]=c1;n2[i]=c2;if(q2.count(n1)!=0)return ans;if(q2.count(n2)!=0)return ans;if(vis.count(n1)==0){vis.insert(n1);q3.insert(n1);}if(vis.count(n2)==0){vis.insert(n2);q3.insert(n2);}}}q1=q3;if(q2.size()<q1.size())swap(q1,q2);}return -1;}
};

04 状态压缩

leetcode 773

class Solution {vector<vector<int>>near={{1,3},{0,2,4},{1,5},{0,4},{1,3,5},{2,4}};
public:int slidingPuzzle(vector<vector<int>>& board) {string st="";for(int i=0;i<2;i++){for(int j=0;j<3;++j){st+=to_string(board[i][j]);}}if(st=="123450")return 0;unordered_set<string>vis;unordered_set<string>q1;unordered_set<string>q2;q1.insert(st);q2.insert("123450");vis.insert(st);vis.insert("123450");int step=0;while(!q1.empty()&&!q2.empty()){step++;unordered_set<string>q3;for(const string cur:q1){vector<string>nex=get_nex(cur);for(string n:nex){if(q2.count(n)!=0)return step;if(vis.count(n)==0){vis.insert(n);q3.insert(n);}}}q1=q3;if(q2.size()<q1.size())swap(q1,q2);}return -1;}vector<string>get_nex(string cur){vector<string>ans;int z=0;while(cur[z]!='0')z++;for(int i:near[z]){string temp=cur;temp[z]=cur[i];temp[i]='0';ans.push_back(temp);}return ans;}
};

05 01BFS

leetcode 2290

class Solution {vector<int>mo={-1,0,1,0,-1};struct p{int x,y;};
public:int minimumObstacles(vector<vector<int>>& g) {int n=g.size();int m=g[0].size();vector<vector<int>>dis(n,vector<int>(m,0x3f3f3f3f));deque<p>q;q.push_front({0,0});dis[0][0]=0;while(q.size()){int siz=q.size();for(int i=0;i<siz;++i){auto [x,y]=q.front();q.pop_front();if(x==n-1&&y==m-1)return dis[x][y];for(int i=0;i<4;++i){int nx=x+mo[i];int ny=y+mo[i+1];if(nx<0||ny<0||nx>=n||ny>=m)continue;int nd=dis[x][y]+g[nx][ny];if(nd<dis[nx][ny]){dis[nx][ny]=nd;if(g[nx][ny]==1){q.push_back({nx,ny});}else q.push_front({nx,ny});}}}}return -1;}
};

06 01BFS

leetcode 1368

class Solution {vector<vector<int>>mo={{},{0,1},{0,-1},{1,0},{-1,0}};struct p{int x,y;};
public:int minCost(vector<vector<int>>& g) {int n=g.size();int m=g[0].size();vector<vector<int>>dis(n,vector<int>(m,0x3f3f3f3f));deque<p>q;q.push_front({0,0});dis[0][0]=0;while(q.size()){int siz=q.size();for(int i=0;i<siz;++i){auto [x,y]=q.front();q.pop_front();if(x==n-1&&y==m-1)return dis[x][y];for(int i=1;i<=4;++i){int nx=x+mo[i][0];int ny=y+mo[i][1];if(nx<0||ny<0||nx>=n||ny>=m)continue;int cost=i==g[x][y]?0:1;int nd=dis[x][y]+cost;if(nd<dis[nx][ny]){dis[nx][ny]=nd;if(cost==1){q.push_back({nx,ny});}else q.push_front({nx,ny});}}}}return -1;}
};

07 01BFS

leetcode 3286

class Solution {vector<int>mo={-1,0,1,0,-1};struct p{int x,y;};
public:bool findSafeWalk(vector<vector<int>>& g, int health) {int n=g.size();int m=g[0].size();vector<vector<int>>dis(n,vector<int>(m,0x3f3f3f3f));deque<p>q;q.push_front({0,0});dis[0][0]=g[0][0];while(q.size()){int siz=q.size();for(int i=0;i<siz;++i){auto [x,y]=q.front();q.pop_front();if(x==n-1&&y==m-1)return dis[x][y]<health;for(int i=0;i<4;++i){int nx=x+mo[i];int ny=y+mo[i+1];if(nx<0||ny<0||nx>=n||ny>=m)continue;int nd=dis[x][y]+g[nx][ny];if(nd<dis[nx][ny]){dis[nx][ny]=nd;if(g[nx][ny]==1){q.push_back({nx,ny});}else q.push_front({nx,ny});}}}}return 0;}
};

08 BFS + DFS

leetcode 126

class Solution {vector<vector<string>>ans;vector<string>path;unordered_map<string,vector<string>>gra;void dfs(string cur,string target){path.push_back(cur);if(cur==target){ans.push_back(path);}else if(gra.count(cur)){for(string nex:gra[cur]){dfs(nex,target);}}path.pop_back();}
public:vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string>words;for(string word:wordList){words.insert(word);}if(words.count(endWord)==0){return vector<vector<string>>();}unordered_set<string>curleve;unordered_set<string>nexleve;bool found=0;curleve.insert(beginWord);while(curleve.size()){for(auto x:curleve){words.erase(x);}for(auto word:curleve){string t=word;int lw=word.size();for(int i=0;i<lw;++i){char old=word[i];for(char ch='a';ch<='z';++ch){if(ch==old)continue;t[i]=ch;if(words.count(t)){if(t==endWord){found=1;}gra[t].push_back(word);nexleve.insert(t);}}t[i]=old;}}if(found)break;curleve=nexleve;nexleve.clear();}if(found){dfs(endWord,beginWord);for(auto &x:ans){reverse(x.begin(),x.end());}}return ans;}
};

09 双向BFS

leetcode 127

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string>words;for(auto x:wordList)words.insert(x);if(words.count(endWord)==0)return 0;unordered_set<string>small;unordered_set<string>big;unordered_set<string>nex;small.insert(beginWord);big.insert(endWord);int ans=1;while(small.size()){ans++;for(auto word:small){string t=word;for(int i=0;i<(int)t.size();++i){for(char ch='a';ch<='z';++ch){if(ch==word[i])continue;t[i]=ch;if(big.count(t))return ans;if(words.count(t)){words.erase(t);nex.insert(t);}}t[i]=word[i];}}if(nex.size()>big.size()){small=big;big=nex;}else{small=nex;}nex.clear();}return 0;}
};
http://www.jsqmd.com/news/296323/

相关文章:

  • LG EXAONE 4.0:双模式AI多语言能力再突破
  • 如何用MOOTDX解决股票数据获取难题?从入门到实战的完整指南
  • 移动开发者的素材资源精准匹配效率指南
  • Moonlight-16B震撼发布:Muon优化让训练效率飙升2倍!
  • Qwen-Image-2512-ComfyUI本地部署教程,适合进阶玩家
  • Wan2.1-VACE-14B:AI视频创作编辑全能工具
  • JanusFlow:极简架构!AI图像理解生成新引擎
  • GPT-OSS-20B:16GB内存轻松跑的本地AI推理引擎
  • TeslaMate智能汽车数据管理系统故障处理指南:从诊断到康复的完整解决方法
  • 艾尔登法环存档修改工具全攻略:从入门到精通的角色定制指南
  • DeepSeek-V3.1双模式AI:智能效率与工具调用新升级
  • 本地金融数据处理新选择:用Python量化工具mootdx实现通达信数据高效读取
  • GLM-Z1-32B开源:320亿参数打造深度推理新模型
  • Emu3.5-Image:10万亿数据打造的全能AI绘图工具!
  • Qwen-Image-2512省电部署方案:低功耗显卡实测案例分享
  • 3D抽奖系统:重塑活动互动体验的技术方案
  • 无需安装依赖:Docker镜像运行SenseVoiceSmall完整教程
  • 探索iOS隐藏技术:RootHide如何让越狱设备隐形于应用检测
  • NextTrace安装完全指南:从入门到精通的场景化方案
  • 企业数据治理全景指南:从标准化到价值可视化的零门槛落地实践
  • 5步构建坚不可摧的Python测试防线:GitHub Actions+Pytest+Codecov全流程实践
  • 系统性能优化完全指南:如何通过精准配置提升游戏体验与系统响应速度
  • 重新定义家庭观影体验:Blink媒体播放器探索者指南
  • AtlasOS显卡性能优化实用指南
  • 高效零成本文档扫描:NAPS2开源工具的全场景解决方案
  • 如何突破网络限制?本地化金融数据处理新方案
  • VS Code LeetCode代码精修指南:提升算法题解效率与编程规范的实战技巧
  • Qwen3-1.7B-FP8:17亿参数AI推理双模式自由切换
  • 零基础玩转AI视频生成:用InfiniteTalk实现图像转视频全攻略
  • LFM2-350M:手机也能跑!2倍速边缘AI轻量模型