leetcode#210 Course Schedule

题目:

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].

这道题是一个典型的拓扑排序问题。首先对于所有的course构成的有向图G(V, E)来说,最先选择的课程一定是没有先修课程的course,用图论的语言来表述就是入度为零。这样我们只要维护一个有向图,每次从中删除一个入度为零的点及其连接的边,将其加入到结果中去。当这个图为空时边求出了这个问题的一个解。但是,当这个图不为空又不存在入度为零的点时,说明这个图中存在环,即不存在解。代码如下:

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        int pre[numCourses];
        for (int i=0; i<numCourses; i++) pre[i]=0;
        vector<vector<int>> adj(numCourses);
        for (int i=0; i<prerequisites.size(); i++) {
            pair<int, int>& tmp = prerequisites[i];
            adj[tmp.second].push_back(tmp.first);
            pre[tmp.first]++;
        }
        vector<int> result;
        int count = 0;
        while(count != numCourses) {
            count = 0;
            for(int i=0; i<numCourses; i++) if (pre[i]==0) {
                pre[i]=-1;
                vector<int> tmp = adj[i];
                for(int j=0; j<tmp.size(); j++) pre[tmp[j]]--;
                result.push_back(i);
            } else count++;
        }
        if (result.size()!=numCourses) result ={};
        return result;
    }
};

这其中我用一个pre数组来维护每个点的入度,用count在每次迭代的时候记录入度非零的点的个数。由于每次从图中删除一个点时,将其入度修改为-1,所以不存在入度为零的点只有两种情况:得到了正确解或者图中存在环所以不存在解。所以在最后检查结果的大小是否与course的个数相等来判定这两种情况。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值