Course Schedule

来源:互联网 发布:杂志排版软件 编辑:程序博客网 时间:2024/05/16 05:40

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.

思路:题目可以转化为求一个图中是否存在环路,采用拓扑排序判断是否存在环路。

  1. 先找出在没有删除任何点和边的情况下,所有入度为0的结点
  2. 将入度为0的结点加入一个队列中
  3. 然后在原图中遍历,从队列中取出入度为0的结点,找出该结点所指向的结点r,并将该边删除,那么将r的入度减一,如果在删除边后,r的入度为0,那么也将r加入队列中,并用一个count来记录可以加入队列中的结点的数目
  4. 题目中说一共有numCourses门课程,如果count等于numCourse说明numCourse门课程存在拓扑序列,说明没有环路。否则说明原图中存在环路。
public class Solution {    public boolean canFinish(int numCourses, int[][] prerequisites) {        int m=prerequisites.length;        if(m==0) return true;        ////inDegree用来存储某一结点的入度,共有numCourses个结点        int[] inDegree=new int[numCourses];        for(int i=0;i<m;i++)        {            inDegree[prerequisites[i][1]]++;        }        //这个队列是用来存储所有入度为0的结点        Queue<Integer> queue=new LinkedList<Integer>();        for(int i=0;i<numCourses;i++)        {            if(inDegree[i]==0) queue.add(i);        }        //count用来统计所有可以加入队列的入度为0的结点数        int count=queue.size();        while(!queue.isEmpty())        {            int temp=queue.remove();            for(int i=0;i<m;i++)            {   //temp为入度为0的点                if(temp==prerequisites[i][0])                  {                      //r为temp所指向的点,删除temp指向r的边,即r的入度要减一                      int r=prerequisites[i][1];                      inDegree[r]--;                      //删除了指向r的边后,如果该点入度为0,将其加入队列中                      if(inDegree[r]==0)                          {  queue.add(r);                             count++;                           }                  }            }        }        //如果在删除边后,所有的结点都可以变成入度为0的结点,那么说明可以完成所有课程        if(count==numCourses) return true;        else return false;    }}
0 0
原创粉丝点击