Course Schedule

来源:互联网 发布:lol皮肤试用软件 编辑:程序博客网 时间:2024/06/06 01:00

[LeetCode]拓扑序(1)

0.题目

leetcode : 207. Course Schedule

1.题目描述

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, is it possible for you to finish all courses?

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 it is possible.

2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

2.题目分析

抛开题目中的修饰部分,这道题要求的其实是: 一个有向图是否存在拓扑序.
在求有向图的拓扑序时,一个比较简单的办法是:
1. 选择一个入度为0的顶点(v)作为输出
2. 将图中所有与该顶点有关的边(只有从v出的边,没有从进入v的边)删除
3. 重复1,2直到图中不再有入度为0的顶点

如果最后图中还有顶点就证明不存在拓扑序。
就本题而言,因为顶点是0-n-1,所以我们可以用二维数组来实现图的存储(下标代表顶点,数组元素代表邻接顶点)。比如array[0] = {1,2}代表顶点0到顶点1、2都有边。
pair[0, 1]代表1必须现在0之前完成,所以我们可以定义一种数据结构存储所有的约束(pair):用一个二维数组保存约束,如果array[0] = {},代表0可以在任意时候完成;如果array[1] = {2,4},那代表1必须在2和4**之后**完成。
算法如下:
1. 选择一个可以从任何时候完成任务完成
2. 删除所有任务中该任务的约束(比如2完成,那array[1] = {4})
3. 重复1,2直到图中所有能完成(没有约束任务)的任务都完成

该算法可以看做是实际情况的模拟:每完成一个任务,以该任务为限制的约束就能够取消。而每一个任务只要没有约束,就能马上(任意)完成

3.代码实现

bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {    vector<int> null;    vector<vector<int> > preCondition(numCourses, null); // 用于保存图的二维数组    int size = prerequisites.size();    for (int i = 0; i < size; i++) {        preCondition[prerequisites[i].first].push_back(prerequisites[i].second);    } // 完成约束条件(Edge)的输入    int flag[numCourses]; // 用于标志是否完成(移除)    for (int i = 0; i < numCourses; i++)        flag[i] = 0;    for (int i = 0; i < numCourses; i++) {        if (flag[i] == 0 && preCondition[i].size() == 0) { // size=0代表没有约束条件=可以完成            flag[i] = 1; // 完成            for (int j = 0; j < numCourses; j++) { // 将该任务的约束删除                for (int k = 0; k < preCondition[j].size(); k++) {                    if (preCondition[j][k] == i) {                        preCondition[j].erase(preCondition[j].begin() + k);                        break;                    }                }            }            i = -1; // 重新查找可以完成的任务        }    }    for (int i = 0; i < numCourses; i++) {        if (preCondition[i].size() != 0)            return false;    } // 判断是否所有任务都已经完成    return true;}

4.结束

代码不够精简,但是已经可以说明算法的思路了。
求解拓扑序有很多方法,有兴趣可以看看书查查资料。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 六个月婴儿发烧怎么办退烧快点 咳嗽20天老不好怎么办 吃过退烧药出汗怎么办 5岁儿童发烧39度怎么办 小孩烧到39度怎么办 儿童7岁发烧39度怎么办 发烧没药怎么办怎样退烧快 小孩发烧怎么办怎样退烧快 发烧头疼怎么办最快最有效 发烧头晕怎么办最快最有效 婴儿发烧怎么办最快最有效 孩子一直37度8怎么办 一岁半宝宝37度5怎么办 发烧打了针35度怎么办 小孩发烧吃了鱼怎么办 八个月婴儿发烧39度怎么办 婴儿反复发烧39度怎么办 宝宝发烧了怎么办如何退烧 宝宝烧到38.8度怎么办 小孩发烧到39度怎么办 宝贝发烧到40度怎么办 孩子发烧39度8怎么办 儿子发烧39度该怎么办 孩子发烧39度7怎么办 7个月婴儿发烧怎么办 感冒了头发很油怎么办 5岁宝宝发烧39度怎么办 婴儿烧到39.5度怎么办 1岁多宝宝39.5度怎么办 宝宝发烧40多度怎么办 7岁宝宝发烧了怎么办 宝宝反复发烧39度怎么办 一岁半宝宝反复发烧39度怎么办 七岁发烧38度怎么办 小孩一直37度1怎么办 婴儿一直37度多怎么办 1岁半高烧39度怎么办 反复发烧39度多怎么办 孩子不爱喝水怎么办%3f 8岁儿童不爱喝水怎么办 儿子14岁了不爱说话怎么办