这题和LeetCode207. 课程表一样,都是拓扑排序的模板题,只不过207题只需判断是否存在拓扑序列,
这题要返回拓扑序列。
只需要在BFS时在一个结果数组中记录每个入队的元素即可,最后判断数组大小是否和课程总数量numCourses相同,相同就返回我们记录的所有元素的入队顺序的数组res,
不相同就返回空数组。
关于拓扑排序,可以看一下上面那个链接里(207题)的步骤,207题搞定了,这题就稍微改一下就可以了。
代码如下:
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> g(numCourses); //g表示课程关系之间的图,g[i]数组存放课程i的所有后继课程
vector<int> inDegree(numCourses); //inDegree[i]表示课程i的入度(先修课程的数量)
for(int i = 0; i < prerequisites.size(); ++i) {
int course1 = prerequisites[i][0], course2 = prerequisites[i][1]; //这题的输入比较奇怪,prerequisties的第一门课是后继课程,第二门课才是先修课程,注意一下顺序
g[course2].push_back(course1); //course2是course1的先修课程
++inDegree[course1]; //course1的先修课程数量加一
}
vector<int> res; //存放拓扑序列
queue<int> q;
for(int i = 0; i < numCourses; ++i) { //拓扑排序最开始把所有入度为0的节点入队
if(inDegree[i] == 0) {
q.push(i);
}
}
while(q.size()) {
int curCourse = q.front(); //队头元素出队,表示这门课程学完了
q.pop();
res.push_back(curCourse);
for(int i = 0; i < g[curCourse].size(); ++i) { //这门学习完的课程的所有后继课程的入度(先修课程数量)可以减一了
--inDegree[g[curCourse][i]];
if(inDegree[g[curCourse][i]] == 0) { //如果入度减一之后为0,则入队
q.push(g[curCourse][i]);
}
}
}
if(res.size() != numCourses) { //无法学习完所有课程,返回空数组
return {};
}
return res; //存在一种包含所有课程的拓扑序列,则返回
}
};