应用为层序遍历树、最短路径
class Solution {public: int openLock(vector<string>& deadends, string target) { unordered_set<string> deads;//记录死亡密码 //初始化死亡密码 for(string s:deadends){ deads.insert(s); } if(deads.count("0000")){ return -1;//锁死 } int step=0; //需要的步数 queue<string> q; q.push("0000"); unordered_set<string> visited; //记录已经穷举过的密码 visited.insert("0000"); while(!q.empty()){ int size=q.size(); for(int i=0;i<size;i++){ string cur=q.front(); q.pop(); //死亡密码,跳过 if(deads.count(cur)){ continue; } //判断是否到达终点 if(cur==target){ return step; } for(int j=0;j<4;j++){ //向上转 string up=plusOne(cur,j); if(!visited.count(up)){ q.push(up); visited.insert(up); } //向下转 string down=minusOne(cur,j); if(!visited.count(down)){ q.push(down); visited.insert(down); } } } step++; } return -1; } string plusOne(string s,int i){ if(s[i]=='9'){ s[i]='0'; }else{ s[i]+=1; } return s; } string minusOne(string s,int i){ if(s[i]=='0'){ s[i]='9'; }else{ s[i]-=1; } return s; }};
//双向BFSclass Solution {public: int openLock(vector<string>& deadends, string target) { unordered_set<string> deads;//记录死亡密码 //初始化死亡密码 for(string s:deadends){ deads.insert(s); } if(deads.count("0000")){ return -1;//锁死 } int step=0; //需要的步数 unordered_set<string> q1,q2; q1.insert("0000"); q2.insert(target); unordered_set<string> visited; //记录已经穷举过的密码 visited.insert("0000"); while(!q1.empty()&&!q2.empty()){ //哈希表在遍历过程中不能修改,用temp存储 unordered_set<string> temp; for(string cur:q1){ //判断是否为死亡密码 if(deads.count(cur)){ continue; } //判断是否到达终点 if(q2.count(cur)){ return step; } visited.insert(cur); //将一个节点的未遍历相邻节点加入集合 for(int i=0;i<4;i++){ string up=plusOne(cur,i); if(!visited.count(up)){ temp.insert(up); } string down=minusOne(cur,i); if(!visited.count(down)){ temp.insert(down); } } } step++; //temp相当于q1 q1=q2; //交换q1,q2,下一轮while就是扩散q2 q2=temp; } return -1; } string plusOne(string s,int i){ if(s[i]=='9'){ s[i]='0'; }else{ s[i]+=1; } return s; } string minusOne(string s,int i){ if(s[i]=='0'){ s[i]='9'; }else{ s[i]-=1; } return s; }};
class Solution {public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { vector<vector<int>> graph(numCourses); vector<int> indgree(numCourses); //统计入度 for(auto p:prerequisites){ int from=p[1],to=p[0]; graph[from].push_back(to); indgree[to]++; } //根据入度将节点加入队列,入度为0加入 queue<int> q; for(int i=0;i<numCourses;i++){ if(indgree[i]==0){ q.push(i); } } int count=0; //记录遍历节点的索引 vector<int> result(numCourses); //记录排序结果 while(!q.empty()){ int cur=q.front(); q.pop(); //弹出节点的顺序就是拓扑排序顺序 result[count]=cur; count++; for(int g:graph[cur]){ //入度-1,为0加入队列 indgree[g]--; if(indgree[g]==0){ q.push(g); } } } if(count!=numCourses){ return {}; } return result; }};