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;
            }
        }
    };
    

    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lllllyt/article/details/83099470