207. Course Schedule

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:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

题目含义: 有从0到n-1共n门课程,且一门课程会有前导课程。例如2, [[1,0]],要学习课程2先要学习课程1,要学习课程1先要学习课程0.。判断schedule是否正确。

 

 1     public boolean canFinish(int numCourses, int[][] prerequisites) {
 2  //     要上prerequisites[i][0]的课,必须先上prerequisites[i][1]的课 题目是要判断给定的序列是否有环路,有的话返回false
 3         // 参数检查
 4         if (prerequisites == null) {
 5             return false;
 6         }
 7         int len = prerequisites.length;
 8         if (numCourses <= 0 || len == 0) {
 9             return true;
10         }
11 
12         // 记录每个course的prerequisites的数量
13         int[] pCounter = new int[numCourses];
14         for (int i = 0; i < len; i++) {
15             pCounter[prerequisites[i][0]]++;  //prerequisites[i][0]这些课程都有前缀课程prerequisites[i][1]
16         }
17         // 用队列记录可以直接访问的course
18         LinkedList<Integer> queue = new LinkedList<Integer>(); //具备上课条件,可以上课的集合
19         for (int i = 0; i < numCourses; i++) {
20             if (pCounter[i] == 0) {
21                 queue.add(i);
22             }
23         }
24 
25         // 取出队列的course,判断
26         int numNoPre = queue.size();
27         while (!queue.isEmpty()) {
28             int top = queue.remove();
29             for (int i = 0; i < len; i++) {
30                 // 该course是某个course的prerequisites
31                 if (prerequisites[i][1] == top) {
32                     pCounter[prerequisites[i][0]]--; //那门课程的前缀课程数可以减一,因为top课程可以上
33                     if (pCounter[prerequisites[i][0]] == 0) {
34                         numNoPre++; //那门课程的前缀课程都可以上了,所以那门课程也可以上了
35                         queue.add(prerequisites[i][0]);  //将那门课程也加到可以上课的队列中
36                     }
37                 }
38             }
39         }
40         return numNoPre == numCourses;       
41     }

 

posted @ 2017-10-24 14:42  daniel456  阅读(112)  评论(0编辑  收藏  举报