1. 程式人生 > >【LeetCode】210. 課程表 II 結題報告 (C++)

【LeetCode】210. 課程表 II 結題報告 (C++)

題目描述:

現在你總共有 n 門課需要選,記為 0 到 n-1。

在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們: [0,1]

給定課程總量以及它們的先決條件,返回你為了學完所有課程所安排的學習順序。

可能會有多個正確的順序,你只要返回一種就可以了。如果不可能完成所有課程,返回一個空陣列。

示例 1:

輸入: 2, [[1,0]] 
輸出: [0,1]
解釋: 總共有 2 門課程。要學習課程 1,你需要先完成課程 0。因此,正確的課程順序為 [0,1] 。
示例 2:

輸入: 4, [[1,0],[2,0],[3,1],[3,2]]
輸出: [0,1,2,3] or [0,2,1,3]
解釋: 總共有 4 門課程。要學習課程 3,你應該先完成課程 1 和課程 2。並且課程 1 和課程 2 都應該排在課程 0 之後。
     因此,一個正確的課程順序是 [0,1,2,3] 。另一個正確的排序是 [0,2,1,3] 。
說明:

輸入的先決條件是由邊緣列表表示的圖形,而不是鄰接矩陣。詳情請參見圖的表示法。
你可以假定輸入的先決條件中沒有重複的邊。
提示:

這個問題相當於查詢一個迴圈是否存在於有向圖中。如果存在迴圈,則不存在拓撲排序,因此不可能選取所有課程進行學習。
通過 DFS 進行拓撲排序 - 一個關於Coursera的精彩視訊教程(21分鐘),介紹拓撲排序的基本概念。
拓撲排序也可以通過 BFS 完成。

解題方案:

與上一題207 課程表的思路是相同的:

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
        pair<int, int> p;
        vector<int> 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;
            ++degree[to];
            args.push_back(heads[from]);
            points.push_back(to);
            heads[from] = count++;
        }
 
        /* bfs拓撲排序,依次移除入度為0的點 */
        queue<int> 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];
            }
        }
 
        /* 判定是否所有的點入度都為0,若是則不存在環,否則存在環 */
        for (int i = 0; i < numCourses; ++i)
            if (degree[i] > 0)
                 return vector<int>();
 
        return ans;
    }
};