问题简述
给定n节课,每节课按0~n-1编号。
在修某些课的时候需要有其它课的基础,必须先上先修课。现在用pair的形式来表示要先修的课,比如 [ [0,1], [1,2] ] 就表示在修课程1之前必须先修课程0,修课程2之前必须修课程1。现在需要给出一个修课的顺序,使得按照该顺序修课可以顺利得到所有学分。
现在的输入为课程数和先修的顺序,输出为修课顺序中的一种。
比如:
例子1
输入:
2, [[1,0]]
表示共有两门课,在修课程1之前必须修课程0
输出:
[0, 1]
表示修课顺序为0->1
又比如:
例子2
输入:
4, [[1,0],[2,0],[3,1],[3,2]]
输出:
[0,1,2,3] 或者 [0,2,1,3](其中一个即可)
再比如:
例子3
输入:
2, [[1,0], [0,1]]
输出:
[]
因为无法满足修课程1之前修课程0,同时修课程0之前修课程1,所以返回空
解决思路
其实这个问题就是让我们在给定的输入下,判断能否完成拓扑排序。何为拓扑排序(详见这里)?
比如,在输入为
4, [[1,0],[2,0],[3,1],[3,2]]
的情况下,得到的下图1就是一个拓扑排序,也就是一个没有环的有向图。
源代码
下面是一个基于BFS的拓扑排序思路,其实也不能说是严格意义上的BFS,只是有点像~
struct Node{
int indegree;
vector<int> adjacency;
Node(){
indegree = 0;
adjacency.clear();
}
};
class Solution {
private:
vector<int> res;
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<Node*> vec;
for (int i = 0; i < numCourses; i++){
vec.push_back(new Node());
}
for (int i = 0; i < prerequisites.size(); i++){
vec[prerequisites[i].first]->indegree++;
vec[prerequisites[i].second]->adjacency.push_back(prerequisites[i].first);
}
for (int i = 0; i < vec.size(); i++){
int j = 0;
for (; j < vec.size(); j++){
if (vec[j]->indegree == 0){
res.push_back(j);
vec[j]->indegree = -1;
for (int item : vec[j]->adjacency){
vec[item]->indegree--;
}
break;
}
}
if (j == vec.size()){
res.clear();
return res;
}
}
return res;
}
};