LeetCode 207. Course Schedule

原题链接在这里:https://leetcode.com/problems/course-schedule/description/

题目:

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.

题解:

topological sort. 每一门课就是一个vertex, 每一个preRequest就是一个edge.

求Course Schedule,等同问题是有向图检测环. 一个DAG的Topological Order可以有大于1种。

常用的Topological Sorting算法有两种

  1. 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. 
  2. 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         //计算每门课的indegree
18         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 edge
33         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 }

跟上Course Schedule IICourse Schedule III.

reference: http://www.cnblogs.com/yrbbest/p/4493547.html

转载于:https://www.cnblogs.com/Dylan-Java-NYC/p/4866470.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值