1. 程式人生 > >[LeetCode] 210. Course Schedule II 課程安排II

[LeetCode] 210. Course Schedule II 課程安排II

tps logic 若是 push_back don ken solution .html gre

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.

For example:

2, [[1,0]]

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]

4, [[1,0],[2,0],[3,1],[3,2]]

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.

Hints:
    1. This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
    2. Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
    3. Topological sort could also be done via BFS.

207. Course Schedule的拓展,解法與其類似,這裏要按順序添加要完成的課程。拓撲排序,最後加一步判斷是否存在環,如果存在環則返回空集合。使用BFS和DFS均可,區別在於是按照入度還是出度來考慮。

C++:

class Solution {
public:
    /** 
     * 完成所有的課程的順序
     * bfs拓撲排序
     * @param numCourses 課程數量
     * @param prerequisites 課程先序關系
     * @return 能完成返回課程順序,否則返回空
     */
    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {
        vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
        pair<int, int> p;
        int from, to, count = 0, len = prerequisites.size();

        /* 構造有向圖,鄰接表 */
        for (int i = 0; i < len; ++i) {
            p = prerequisites[i];
            from = p.second;
            to = p.first;
            ++degree[to];
            args.push_back(heads[from]);
            points.push_back(to);
            heads[from] = count++;
        }   

        /* bfs拓撲排序,依次移除入度為0的點 */
        vector<int> ret;
        queue<int> q;
        for (int i = 0; i < numCourses; ++i) 
            if (degree[i] == 0) q.push(i);
        while (!q.empty()) {
            from = q.front();
            ret.push_back(from); // 課程完成,添加到結果集中
            q.pop();
            to = heads[from];
            while (to != -1) {
                if(--degree[points[to]] == 0) q.push(points[to]);
                to = args[to];
            }   
        }   

        /* 判定是否所有的點入度都為0,若是則不存在環,否則存在環 */
        for (int i = 0; i < numCourses; ++i)
            if (degree[i] > 0) {
                ret.clear();
                break;
            }   

        return ret;
    }   
};

C++:DFS

class Solution {
public:
    /** 
     * 完成所有的課程的順序
     * dfs拓撲排序
     * @param numCourses 課程數量
     * @param prerequisites 課程先序關系
     * @return 能完成返回課程順序,否則返回空
     */
    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {
        vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
        pair<int, int> p;
        int from, to, count = 0, len = prerequisites.size();

        /* 構造有向圖,鄰接表 */
        for (int i = 0; i < len; ++i) {
            p = prerequisites[i];
            from = p.second;
            to = p.first;
            ++degree[from];
            args.push_back(heads[to]);
            points.push_back(from);
            heads[to] = count++;
        }   

        /* dfs拓撲排序,依次移除出度為0的點 */
        vector<int> ret;
        queue<int> q;
        for (int i = 0; i < numCourses; ++i) 
            if (degree[i] == 0) q.push(i);
        while (!q.empty()) {
            to = q.front();
            ret.push_back(to); // 課程完成添加到結果集中
            q.pop();
            from = heads[to];
            while (from != -1) {
                if(--degree[points[from]] == 0) q.push(points[from]);
                from = args[from];
            }   
        }   

        /* 判定是否所有的點入度都為0,若是則不存在環,否則存在環 */
        for (int i = 0; i < numCourses; ++i)
            if (degree[i] > 0) {
                ret.clear();
                break;
        }   

        /* 逆序 */
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

  

  

[LeetCode] 210. Course Schedule II 課程安排II