# 课程表 II

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai必须 先选修 bi

返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组

 

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:[0,1]
解释:总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入:numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出:[0,2,1,3]
解释:总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

示例 3:

输入:numCourses = 1, prerequisites = []
输出:[0]

 

提示:

 

拓展:

以下错误的选项是?

## aop ### before ```cpp #include using namespace std; ``` ### after ```cpp ``` ## 答案 ```cpp class Solution { public: vector findOrder(int numCourses, vector> &prerequisites) { vector heads(numCourses, -1), degree(numCourses, 0), points, args; pair p; vector ans; int from, to, count = 0, len = prerequisites.size(); for (int i = 0; i < len; ++i) { p = prerequisites[i]; from = p.second; to = p.first; args.push_back(heads[from]); points.push_back(to); heads[from] = count++; } queue q; for (int i = 0; i < numCourses; ++i) if (degree[i] == 0) { q.push(i); ans.push_back(i); } while (!q.empty()) { from = q.front(); q.pop(); to = heads[from]; while (to != -1) { if (--degree[points[to]] == 0) { q.push(points[to]); ans.push_back(points[to]); } to = args[to]; } } for (int i = 0; i < numCourses; ++i) if (degree[i] > 0) return vector(); return ans; } }; ``` ## 选项 ### A ```cpp class Solution { public: vector findOrder(int numCourses, vector> &prerequisites) { int n = numCourses; vector> g(n); vector m(n); for (auto &e : prerequisites) { int i = e[0], j = e[1]; g[j].insert(i), m[i]++; } queue q; auto f = [&](int i) { if (!m[i]) q.push(i); }; for (int i = 0; i < n; i++) f(i); vector res; while (n--) { if (q.empty()) return {}; int i = q.front(); q.pop(); res.push_back(i); for (int j : g[i]) m[j]--, f(j); } return res; } }; ``` ### B ```cpp class Solution { private: vector> edges; vector visited; vector result; bool invalid; public: void dfs(int u) { visited[u] = 1; for (int v : edges[u]) { if (visited[v] == 0) { dfs(v); if (invalid) { return; } } else if (visited[v] == 1) { invalid = true; return; } } visited[u] = 2; result.push_back(u); } vector findOrder(int numCourses, vector> &prerequisites) { edges.resize(numCourses); visited.resize(numCourses); for (const auto &info : prerequisites) { edges[info[1]].push_back(info[0]); } for (int i = 0; i < numCourses && !invalid; ++i) { if (!visited[i]) { dfs(i); } } if (invalid) { return {}; } reverse(result.begin(), result.end()); return result; } }; ``` ### C ```cpp class Solution { public: vector findOrder(int numCourses, vector> &prerequisites) { vector result; vector fake; vector degree(numCourses, 0); unordered_map> map; for (vector prerequisite : prerequisites) { map[prerequisite[1]].push_back(prerequisite[0]); degree[prerequisite[0]]++; } queue q; for (int i = 0; i < numCourses; i++) { if (degree[i] == 0) { q.push(i); } } while (!q.empty()) { int cur = q.front(); result.push_back(cur); q.pop(); for (int next : map[cur]) { degree[next]--; if (degree[next] == 0) q.push(next); } } return result.size() == numCourses ? result : fake; } }; ```