Course Schedule II

解题思路

  • 拓扑排序
  • 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;
    }
};