文章目录
1.No.210课程表Ⅱ–拓扑排序
题目描述:现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。
例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。
难度:中等
示例:
课程表Ⅱ
题解:
用队列存储入度为0的结点,将入度为0的点从表中删除(将其指向的边的入度减一),更新队列中的结点,直到找不到入度为0的点,如果所有点都遍历过,则找到了一个拓扑有序序列,否则该图有环。
//边表结点
typedef struct edgeNode{
int vex;
edgeNode* next;
edgeNode(){next=NULL;}
edgeNode(int val){vex=val;next=NULL;}
}edgeNode;
//顶点结点
typedef struct Node{
edgeNode* first;
int indegree;//入度
Node(){indegree=0;first=new edgeNode;first->next=NULL;}
}Node;
class Solution {
Node* nodes;//边表头指针
public:
vector<int> TopologicalSort(int n){
queue<int> q;
vector<int> ans;
for(int i=0;i<n;i++){
if(nodes[i].indegree==0){
q.push(i);
}
}//入度为0的点入队
int cnt=0;
while(!q.empty()){
cnt++;
int temp=q.front();
q.pop();
ans.push_back(temp);
edgeNode* cur=nodes[temp].first->next;
while(cur!=NULL){
nodes[cur->vex].indegree--;
if(nodes[cur->vex].indegree==0)
q.push(cur->vex);
cur=cur->next;
}
}
if(cnt==n)
return ans;
else
return {};
}
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
nodes=new Node[numCourses];
for(int i=0;i<prerequisites.size();i++){//邻接表建图
edgeNode* temp=new edgeNode(prerequisites[i][0]);
temp->next=nodes[prerequisites[i][1]].first->next;
nodes[prerequisites[i][1]].first->next=temp;
nodes[prerequisites[i][0]].indegree++;
}
// for(int i=0;i<numCourses;i++)
// cout<<nodes[i].indegree<<" ";
return TopologicalSort(numCourses);
}
};