解题思路
- 拓扑排序
- DFS 和 BFS 均可得到结果。
代码
// BFS
class Solution {
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
auto graph = makeGraph(numCourses, prerequisites);
auto degree = makeDegree(graph);
queue<int> root;
vector<int> path;
for (int i = 0; i < numCourses; ++i) {
if (degree[i] == 0) {
root.push(i);
}
}
while (!root.empty()) {
int node = root.front();
path.push_back(node);
root.pop();
for (int i : graph[node]) {
if (--degree[i] == 0) {
root.push(i);
}
}
}
if (path.size() != numCourses) {
return vector<int>();
} else {
return path;
}
}
vector<set<int>> makeGraph(int numCourses, const vector<pair<int, int>>& prerequisites) {
vector<set<int>> graph(numCourses);
for (auto c : prerequisites) {
graph[c.second].insert(c.first);
}
return graph;
}
vector<int> makeDegree(const vector<set<int>>& graph) {
vector<int> degree(graph.size(), 0);
for (auto childs : graph) {
for (int c : childs) {
degree[c]++;
}
}
return degree;
}
};
// DFS
class Solution {
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
auto graph = makeGraph(numCourses, prerequisites);
vector<bool> pathed(numCourses, false);
vector<bool> marked(numCourses, false);
vector<int> sorted;
for (int i = 0; i < numCourses; ++i) {
if (!marked[i] && hasCircle(graph, i, marked, pathed, sorted)) {
return {};
}
}
reverse(sorted.begin(), sorted.end());
return sorted;
}
bool hasCircle(const vector<set<int>>& graph, int node, vector<bool>& marked, vector<bool>& pathed, vector<int>& sorted) {
if (marked[node]) {
return false;
}
marked[node] = pathed[node] = true;
for (int child : graph[node]) {
if (pathed[child] || hasCircle(graph, child, marked, pathed, sorted)) {
return true;
}
}
sorted.push_back(node);
pathed[node] = false;
return false;
}
vector<set<int>> makeGraph(int numCourses, const vector<pair<int, int>>& prerequisites) {
vector<set<int>> graph(numCourses);
for (auto c : prerequisites) {
graph[c.second].insert(c.first);
}
return graph;
}
};