【LeetCode】Course Schedule--拓扑排序
来源:互联网 发布:淘宝天猫客服电话 编辑:程序博客网 时间:2024/06/05 06:17
【题目】
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.
分析:这道题主要是看课程之间是否存在相互依赖关系,从图论角度见是否构成环。
环的入度永远不会为0,因此,本题的思想是先找出入度为0的点,然后加入到list中,然后从list中弹出,获取元素的相临节点(通过map),然后将对应节点的入度–,当为0时,加入到list中。
当list为空时,此时如果还有num不为-1,未处理,那么就表示课程之间存在环。返回false;
代码如下:400ms
典型的拓扑排序。原理也很简单,在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在)。
回顾一下图的三种表示方式:边表示法(即题目中表示方法),邻接表法,邻接矩阵。用邻接表存储图比较方便寻找入度为0的节点。
【Java代码】
注意,输入可能有重复的边,所以邻接表用HashSet存储。
下面一种代码是不用HashSet的,对于重复的边,它在邻接表中村了两份,同时计算入度时也算了两次,所以代码不会有问题。但个人感觉最好用HashSet,这样符合图的定义。
下面的代码还是比较典型的BFS写法,大家可以对比理解下:
题解:
topological sort. 每一门课就是一个vertex, 每一个preRequest就是一个edge.
求Course Schedule,等同问题是有向图检测环. 一个DAG的Topological Order可以有大于1种。
常用的Topological Sorting算法有两种
- Kahn's Algorithms (wiki): BFS based, start from with vertices with 0 incoming edge,insert them into list S,at the same time we remove all their outgoing edges,after that find new vertices with 0 incoming edges and go on.
- Tarjan's Algorithms (wiki): DFS based, loop through each node of the graph in an arbitrary order,initiating a depth-first search that terminates when it hits any node that has already been visited since the beginning of the topological sort or the node has no outgoing edges (i.e. a leaf node).
Time Complexity: O(V + E). Space: O(V).
AC Java:
1 public class Solution { 2 public boolean canFinish(int numCourses, int[][] prerequisites) { 3 //BFS based 4 if(numCourses <= 0){ 5 return true; 6 } 7 8 //用List<List>建立 adjancy list 9 List<List<Integer>> fromTo = new ArrayList<List<Integer>>();10 for(int i = 0; i<numCourses; i++){11 fromTo.add(new ArrayList<Integer>());12 }13 for(int [] edge: prerequisites){14 fromTo.get(edge[1]).add(edge[0]);15 }16 17 //计算每门课的indegree18 int [] inDegree = new int[numCourses];19 for(int [] edge : prerequisites){20 inDegree[edge[0]]++;21 }22 23 //把indegree为0的课加到queue里面24 List<Integer> res = new ArrayList<Integer>();25 LinkedList<Integer> que = new LinkedList<Integer>();26 for(int i = 0; i<inDegree.length; i++){27 if(inDegree[i] == 0){28 que.add(i);29 }30 }31 32 //从queue里poll出来的课程 去掉他们的outdegree edge33 while(!que.isEmpty()){34 int source = que.poll();35 res.add(source);36 37 for(int destination: fromTo.get(source)){38 inDegree[destination]--;39 //若是终点的indegree减一后变成0, 就加到queue中.40 if(inDegree[destination] == 0){41 que.add(destination);42 }43 }44 }45 return res.size() == numCourses;46 }47 }
- 【LeetCode】Course Schedule--拓扑排序
- LeetCode Course Schedule II 拓扑排序
- Leetcode 210 Course Schedule II 拓扑排序
- leetcode 207. Course Schedule(拓扑排序)
- Course Schedule 拓扑排序
- Course Schedule[拓扑排序]
- Course Schedule II 拓扑排序
- 拓扑排序:课程表Course Schedule
- leetcode(207) Course Schedule即拓扑排序讲解
- LeetCode OJ 207. Course Schedule 拓扑排序+邻接表
- LeetCode 210. Course Schedule II|图问题.拓扑排序
- leetcode 207. Course Schedule 课程调度 + 拓扑排序
- leetcode 210. Course Schedule II 拓扑排序 + HashSet
- Leetcode解题笔记 207.Course Schedule [Medium] 拓扑排序
- 207. Course Schedule 广度优先&&拓扑排序
- 210. Course Schedule II 【Medium】 拓扑排序
- 算法(七)Course Schedule 拓扑排序
- 拓扑排序解210. Course Schedule II
- ios 解决NSTimer 进入后台循环失效
- Java线程同步lock和unlock的用法
- RecyclerView的基本使用(一)
- 表单 (form) JSP ajax http 请求和响应格式
- Spark基础与Java Api介绍
- 【LeetCode】Course Schedule--拓扑排序
- 用VsCode编辑TypeScript
- python re 模块 findall 函数
- java 文件下载实例
- sql
- Please make sure you have the correct access rights and the repository exists.解决方法
- 运算符a++和++a的区别
- smokeping
- ssh闲置一段时间自动登出问题的解决