题目重现:
方法一: 根据拓扑排序的人工模拟推导的算法
基本思想就是统计每个节点的入度
入度为0进入队列
在循环中每次 从队列中移出一个元素
并把它指向的元素入度减一 同样的入度为0进入队列
当队列为空 或者 次数达到numCourse 退出循环
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
queue<int> q; vector<int> ans;
vector<int> count(numCourses,0);
unordered_map<int,vector<int>> mp;
for(auto it:prerequisites){
mp[it[1]].push_back(it[0]);
count[it[0]]++;
}
for(int i=0;i<numCourses;i++){
if(count[i]==0) q.push(i);
}
int cnt=0;
while(cnt<numCourses && !q.empty()){
cnt++;
int head=q.front();
for(auto it:mp[head]){
count[it]--;
if(count[it]==0) q.push(it);
}
ans.push_back(head);
q.pop();
}
if(cnt==numCourses) return ans;
else return vector<int>();
}
};
方法二: dfs深度优先搜索
首先对于一个有向无环图 是一定存在拓扑排序的
但是对于一个有环图 是不可能存在拓扑排序的
对于每一个节点 都有三种状态 0未搜索 1搜索中 2搜索完成
每次我们选一个 未搜索0 的节点 ,把它改成搜索中1 然后访问它的相邻节点
如果它的相邻节点都访问完了, 再次回到该节点的时候 ,那么这个节点其实也访问完成了 标记为2 入栈
但是如果在访问过程中出现了 某个节点是 搜索中1 说明出现了环 不存在拓扑排序
假设我们当前访问到了节点u, 发现它的全部相邻节点都已经搜索完成
那么这些相邻节点其实都已经在栈中了 这个时候我们把u入栈
最后的节点访问顺序其实是从栈底部到栈顶的
class Solution {
public:
bool valid=true;
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> visited(numCourses,0);
vector<int> result;
vector<vector<int>> edges(numCourses,vector<int>());
for(auto it:prerequisites){
edges[it[1]].push_back(it[0]);
}
for(int i=0;i<numCourses;i++){
if(!visited[i])
dfs(i,visited,edges,result);
}
reverse(result.begin(),result.end());
return valid ? result:vector<int>();
}
void dfs(int u,vector<int>& visited,vector<vector<int>>& edges,vector<int>& result){
visited[u]=1;
for(auto v:edges[u]){
if(!visited[v]){
dfs(v,visited,edges,result);
}else if(visited[v]==1){
valid=false;
return;
}
}
visited[u]=2;
result.push_back(u);
}
};