題目網址:https://leetcode.cn/problems/course-schedule-ii/
題意:你這學期必須選修 numCourses
門課程, 標記為 0
到 numCourses - 1
。
在修習某些課程前需要一些先修課程 prerequisites
, 其中 prerequisites[i] = [a_i, b_i]
, 表示要修 a_i
前必須先修 b_i
。
- e.g.
[0, 1]
表示想要修課程 0
, 需要先完成課程 1
。
返回能夠學習完所有可成的學習順序。可能會有很多種正確的順序, 只要返回其中一種就行。若不可能完成所有課程, 則返回空 list。

Solution 1:
想法:利用 Topological Sort + BFS, 同 207. Course Schedule
class Solution { public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { vector<int> inDegree(numCourses, 0); vector<vector<int>> adj(numCourses);
for (const auto& pre : prerequisites) { adj[pre[1]].emplace_back(pre[0]); ++inDegree[pre[0]]; }
queue<int> q; for (int i = 0; i < numCourses; ++i) { if (inDegree[i] == 0) { q.emplace(i); } }
vector<int> res; while (!q.empty()) { const auto cur = q.front(); q.pop(); res.emplace_back(cur);
for (const auto& v : adj[cur]) { if (--inDegree[v] == 0) { q.emplace(v); } } } return (res.size() == numCourses) ? res : vector<int>(); } };
|
- time:$O(n + m)$ ➔
n
為課程數(vertex), m
為先修課程數(edge)。其實就是對圖進行 BFS 所需之時間複雜度 $O(V+E)$
- space:$O(n + m)$ ➔ 因為
adj
為 $O(V+E)$, V
是因為要記錄所有點, E
是因為會記錄所有邊
Solution 2:
想法:利用 Topological Sort + DFS, 同 207. Course Schedule
class Solution { public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { vector<vector<int>> adj(numCourses); for (const auto& pre : prerequisites) { adj[pre[0]].emplace_back(pre[1]); }
vector<int> states(numCourses, 0); for (int i = 0; i < numCourses; ++i) { if (dfs(i, states, adj)) { return {}; } }
return res; }
private: vector<int> res;
bool dfs(const int i, vector<int>& states, vector<vector<int>>& adj){ if (states[i] == 1) { return true; }
if (states[i] == 2) { return false; }
states[i] = 1;
for (const auto& v : adj[i]) { if (dfs(v, states, adj)) { return true; } }
states[i] = 2; res.emplace_back(i);
return false; } };
|
- time:$O(n + m)$ ➔
n
為課程數(vertex), m
為先修課程數(edge)。其實就是對圖進行 DFS 所需之時間複雜度 $O(V+E)$
- space:$O(n + m)$ ➔ 因為
adj
為 $O(V+E)$, V
是因為要記錄所有點, E
是因為會記錄所有邊