LeetCode:210. Course Schedule II

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

    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值