LintCode_安排课程

来源:互联网 发布:mac分屏 编辑:程序博客网 时间:2024/06/05 17:24

你需要去上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] 


思路:也就个拓扑排序,不过注意的是,题中并没有注明给出的图一定是有向无环图(DAG),所以在DFS递归的时候要顺便测试是否存在环,测试的方法也很简单。首先图中的每个节点有三个状态:一是未发现,二是已发现但未访问(仍可以继续递归下去), 三是已访问。若发现u所指向的v已经被发现,则说明存在一个环,及时退出递归返回一个空的结果。

另外也要注意数组的下标太大的话要把它声明成全局变量,或者使用 malloc函数分配内存。

    vector<int> neighbors[100002]; //邻居集合    int status[100002];  //是否被访问过,0-未访问,1-被发现,2-已访问    //数组下标太大了得声明成一个全局变量class Solution {public:    /**     * @param numCourses a total of n courses     * @param prerequisites a list of prerequisite pairs     * @return the course order     */    vector<int> result;    bool dfs(int r)    {        status[r]=1;        for(int i=0;i<neighbors[r].size();i++)        {            if(status[neighbors[r][i]]==0)            {                if(dfs(neighbors[r][i])==false)  //回退                    return false;            }            else if(status[neighbors[r][i]]==1)  //如果发现一个邻居已经被发现了,则说明图中存在环,不是DAG                return false; //所以要及时回退        }        result.push_back(r);        status[r]=2;  //这个一定要记得写        return true;    }    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {        // Write your code here        for(int i=0;i<numCourses;i++) status[i]=0;        for(int i=0;i<prerequisites.size();i++)        {            neighbors[prerequisites[i].second].push_back(prerequisites[i].first);        }        for(int i=0;i<numCourses;i++)        {            if(status[i]==0)                if(dfs(i)==false)  //若存在一个环,应返回一个空的vector                {                    result.clear();                    return result;                }        }        reverse(result.begin(),result.end());        return result;    }};


原创粉丝点击