LeetCode -- Course Schedule
来源:互联网 发布:立项依据怎么写 知乎 编辑:程序博客网 时间:2024/04/24 08:45
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.Note:The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
查阅题目知:实际上是求一个图中是否存在环。可以考虑使用拓扑排序。
拓扑排序:
拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。
这样说,可能理解起来比较抽象。下面通过简单的例子进行说明!
例如,一个项目包括A、B、C、D四个子部分来完成,并且A依赖于B和D,C依赖于D。现在要制定一个计划,写出A、B、C、D的执行顺序。这时,就可以利用到拓扑排序,它就是用来确定事物发生的顺序的。
在拓扑排序中,如果存在一条从顶点A到顶点B的路径,那么在排序结果中B出现在A的后面。
拓扑排序算法的基本步骤:
1. 构造一个队列Q(queue) 和 拓扑排序的结果队列T(topological);
2. 把所有没有依赖顶点的节点放入Q;
3. 当Q还有顶点的时候,执行下面步骤:
3.1 从Q中取出一个顶点n(将n从Q中删掉),并放入T(将n加入到结果集中);
3.2 对n每一个邻接点m(n是起点,m是终点);
3.2.1 去掉边
public class Solution { /* * 拓扑排序 * 1. 选择入度为0的点 * 2. 将选中的点从图中去掉 */ public boolean canFinish(int numCourses, int[][] prerequisites) { //图使用邻接矩阵表示 int[][] E = new int[numCourses][numCourses]; //顶点的入度 long[] degree = new long[numCourses]; if(numCourses <= 1 ){ return true; } //构造图矩阵 //E[i][j]表示i的前驱是j for(int i = 0 ; i < prerequisites.length ; i ++){ E[prerequisites[i][0]][prerequisites[i][1]] = 1; degree[prerequisites[i][1]] ++; } //初始化入度 for(int j = 0;j < numCourses; j ++){ for(int i = 0; i < numCourses;i++){ if(E[i][j] == 1){ degree[j] ++; } } } //判断 while(true){ int var = select0(degree); if(var > -1){ delete0(var,E,degree); }else{ break; } } for(int i = 0; i < degree.length;i ++){ if(degree[i] != Long.MAX_VALUE){ return false; } } return true; } //选择入度为0 public int select0(long[] degree){ for(int i = 0; i < degree.length;i++){ if(degree[i] == 0){ //degree[i] = Long.MAX_VALUE; return i; } } return -1; } //将点从图中去掉 public void delete0(int var, int[][] E,long[] degree){ degree[var] = Long.MAX_VALUE; for(int j = 0; j < E.length;j++){ if(E[var][j] == 1){ degree[j]--; } } }}
尝试之后显示Status: Time Limit Exceeded
参阅网上的解法,显然都是用拓扑排序的思想,那么自己的程序速度在哪慢了?
//构造图矩阵 //E[i][j]表示i的前驱是j for(int i = 0 ; i < prerequisites.length ; i ++){ E[prerequisites[i][0]][prerequisites[i][1]] = 1; degree[prerequisites[i][1]] ++; } //初始化入度 for(int j = 0;j < numCourses; j ++){ for(int i = 0; i < numCourses;i++){ if(E[i][j] == 1){ degree[j] ++; } } }
显然在构造邻接矩阵的时候就可以构造出入度数组,如
for(int i = 0 ; i < prerequisites.length ; i ++){ if(E[prerequisites[i][0]][prerequisites[i][1]] == 0){ E[prerequisites[i][0]][prerequisites[i][1]] = 1; degree[prerequisites[i][1]] ++; } }
需要注意的是:prerequisite[i][j]可能会出现相同的序列对,如{{5,8},{3,5},{1,9},{4,5},{0,2},{1,9},{7,8},{4,9}};
0 0
- Leetcode-Course Schedule && Course Schedule II
- leetcode-Course Schedule
- LeetCode 207 - Course Schedule
- [LeetCode] Course Schedule
- LeetCode Course Schedule
- [leetcode] Course Schedule
- Leetcode Course Schedule
- [leetcode]Course Schedule
- leetcode:Course Schedule
- [leetcode]Course Schedule II
- leetcode - Course Schedule II
- LeetCode Course Schedule II
- [leetcode] Course Schedule II
- [leetcode]Course Schedule
- leetcode:Course Schedule II
- [LeetCode] Course Schedule II
- Leetcode Course Schedule II
- leetcode 207: Course Schedule
- 通过AFNetworking下载网络闪屏用的图片并存储到本地同时获取header头相关信息
- 规则引擎需求(捕捉业务规则需求,将需求转换为规则引擎)
- java 多线程之优先级简单代码
- 如何生成android的keystore文件
- GRE写作必备句型
- LeetCode -- Course Schedule
- 微信卡券开发错误自排查参考文档
- Cocos2d打包安卓APK
- 面向对象
- C语言inline函数
- 一般题模板
- 二叉树的前序、中序、后续遍历,递归、非递归实现
- AICL(Auto Input Current Limited)
- 《深入浅出struts2》--第四章,OGNL