问题简述
给定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;}
};