1. 程式人生 > >LeetCode:207. Course Schedule II(Week 7)

LeetCode:207. Course Schedule II(Week 7)

207. Course Schedule II

  • 題目
    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.

    Example 1:

    Input: 2, [[1,0]] 
    Output: [0,1]
    Explanation: 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] .
    

    Example 2:

    Input: 4, [[1,0],[2,0],[3,1],[3,2]]
    Output: [0,1,2,3] or [0,2,1,3]
    Explanation: 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.
    • You may assume that there are no duplicate edges in the input prerequisites.
  • 解題思路

    • 這題與上週的LeetCode:207. Course Schedule題意差不多,只不過Course Schedule只需判斷能否順利修完課程,Course Schedule ll需要先判斷能否修完,能修完需要返回一個選修的順序,否則返回一個空的。
    • 思路與上週介紹的實現相同,只是對程式碼進行優化。
    • 具體步驟
      • 建立鄰接表,關係為後修過程,即每個課程儲存需先修完該課程才能修的課程。同時得出每個課程的入度,即每個課程需要的先修課程的數目
      • 將入度為0的課程加入佇列中,同時將該課程鄰接表儲存的後修課程的入度減1,判斷修改後的節點的度數是否為0,為0則加入佇列中(注:每當節點加入到佇列中,同時也加入到拓撲排序的陣列中)
      • 重複上述步驟,直到佇列為空
      • 判斷陣列與課程的數是否相等,相等則證明可以拓撲排序,否則證明存在未被加入的課程並且無法完成的課程(課程選修關係存在環)
  • 實現程式碼

    class Solution {
    public:
        vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
            vector<int> v;
            int inDegree[numCourses] = {0}; // 記錄課程需要先修課程的數量
    
    
            // 對應儲存需要修完該課程才能修的課程
            vector<vector<int> > myVec(numCourses);
            for(auto it : prerequisites) {
                inDegree[it.first]++;
                myVec[it.second].push_back(it.first);
            }
    
            queue<int> q;
    
            for(int i = 0; i < numCourses; ++i) {
                if(inDegree[i] == 0) {
                    v.push_back(i);
                    q.push(i);
                }
            }
    
            while(!q.empty()) {
                int size = q.size();
                for(int i = 0; i < size; ++i) {
                    int tmp = q.front();
                    q.pop();
                    for (int j = 0; j < myVec[tmp].size(); ++j) {
                        inDegree[myVec[tmp][j]]--;
                        if(inDegree[myVec[tmp][j]] == 0) {
                            v.push_back(myVec[tmp][j]);
                            q.push(myVec[tmp][j]);
                        }
                    }
                }
            }
    
            if(v.size() == numCourses) 
                return v;
            else {
                v.clear();
                return v;
            }
        }
    };
    

    在這裡插入圖片描述