210. Course Schedule II
问题描述:
There are a total of n courses you have to take, labeled from 0
to n-1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
Example 1:
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] .
Note:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- You may assume that there are no duplicate edges in the input prerequisites.
解题思路:
这其实是 Course Schedule I 的变形题目
在Course Schedule I 中,我们被要求判断是否能够完成课程,即判断图中是否存在环,可以用DFS配合visited数组来做。
在这里要求我们返回上课顺序。
其实是要求我们求图的拓扑排序。
复习一下拓扑排序:
“对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。”
我们可以用出度和入度来做这道题
在初始化图的时候同时更新该顶点的入度(注意:边从基础课指向高级课)
将入度为0的点加入queue
取出queue中的点,并将其加入到返回数组中,对该点能够到达的点的入度进行更新(即减一),若邻接点入度为0,则将该点加入到队列中。
队列为空时检查返回数组的大小是否等于课程数目
若不等于,则说明存在环,清空返回数组。
代码:
class Solution { public: vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) { vector<vector<int>> adj_list(numCourses); vector<int> in_degree(numCourses, 0); vector<int> ret; for(auto p : prerequisites){ adj_list[p.second].push_back(p.first); in_degree[p.first]++; } queue<int> q; for(int i = 0; i < numCourses; i++){ if(in_degree[i] == 0) q.push(i); } while(!q.empty()){ int cur = q.front(); q.pop(); ret.push_back(cur); for(int i : adj_list[cur]){ in_degree[i]--; if(in_degree[i] == 0) q.push(i); } } if(ret.size() != numCourses) ret.clear(); return ret; } };