LintCode 安排课程

你需要去上n门九章的课才能获得offer,这些课被标号为 0 到 n-1 。
有一些课程需要“前置课程”,比如如果你要上课程0,你需要先学课程1,我们用一个匹配来表示他们: [0,1]

给你课程的总数量和一些前置课程的需求,返回你为了学完所有课程所安排的学习顺序。

可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

样例

给定 n = 2, prerequisites = [[1,0]]
返回 [0,1]

给定 n = 4, prerequisites = [1,0],[2,0],[3,1],[3,2]]
返回 [0,1,2,3] or [0,2,1,3]

思路

拓扑排序,采用宽度优先搜索的方式。

遍历找出每门课有几门前置课,以及它所有的后置课。

找出前置课门数为 0 可以直接上的课程,将他们的后置课的前置课门数减 1,若减 1 后前置课门数为 0 了表示这门课也能上了,加入到下一轮要上的课程之中。如此反复,上完所有能上的课,若门数与总门数相同则可以完成课程,返回完成顺序,不同则不能完成,返回空数组。

参考拓扑排序算法 http://blog.csdn.net/dm_vincent/article/details/7714519

    vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> r; r.reserve(numCourses);
        vector<int> indegrees(numCourses, 0);
        vector<vector<int>> childs; childs.resize(numCourses);
        for(int i = 0; i < prerequisites.size(); ++i) {
            pair<int, int>& t = prerequisites[i];
            ++indegrees[t.first];
            childs[t.second].push_back(t.first);
        }
        vector<int>* buf = new vector<int>();
        vector<int>* buf2 = new vector<int>();
        for(int i = 0; i < numCourses; ++i) {
            if(indegrees[i] == 0) {
                r.push_back(i);
                buf->push_back(i);
            }
        }
        while(buf->size()) {
            buf2->clear();
            for(int i = 0; i < buf->size(); ++i) {
                vector<int>& arr = childs[(*buf)[i]];    
                for(int j = 0; j < arr.size(); ++j) {
                    if(--indegrees[arr[j]] == 0) {
                        r.push_back(arr[j]);
                        buf2->push_back(arr[j]);
                    }
                }
            }
            vector<int>* tmp = buf;
            buf = buf2;
            buf2 = tmp;
        }
        if(r.size() < numCourses) return vector<int>();
        return r;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值