Course Schedule II
这一周还是图的问题
LeetCode上的210题:https://leetcode.com/problems/course-schedule-ii
题目
给出n个课程,有些课程需要其他课程的预备知识,即只有学习了其他课程之后才能学该课程。[1, 0]表示要学习1课程必须先学习0课程。给出这样的边和课程的数量,输出一种学习课程的顺序。
Example1:
Input: 2, [[1,0]]
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
course 0. So the correct course order is [0,1] .
Example 2 :
Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [0,2,1,3]
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
题解
仔细思考题目可知题解就是一种拓扑排序的序列,所谓拓扑排序就是图中所有节点的一个序列,序列满足如下条件:对于每一条边[u, v],序列中u必在v之前。也因此图中无环。
求拓扑序列有几种方法,其一可以找到图中入度为0的节点,将其加入排序中,并删除以该节点为起点的边,继续寻找入度为0的节点,一直循环直至没有入度为0的节点。也可以用DFS算法遍历图,记录每个节点的完成顺序,节点完成顺序的降序就是一种拓扑序列。这里用的是第一种算法。
代码
class Solution {
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> adjacent_list(numCourses);
vector<int> in_degree(numCourses);
queue<int> _queue;
vector<int> res;
for (auto &edge : prerequisites) {
adjacent_list[edge.second].push_back(edge.first);
in_degree[edge.first]++;
}
for (int i = 0; i < numCourses; i++) {
if (in_degree[i] == 0) {
_queue.push(i);
}
}
while (_queue.size()) {
int vetrix = _queue.front();
for (auto v : adjacent_list[vetrix]) {
if (--in_degree[v] == 0) {
_queue.push(v);
}
}
res.push_back(vetrix);
_queue.pop();
}
return res.size() == numCourses ? res : vector<int>();
}
};