LeetCode刷题MEDIM篇Course Schedule II

题目

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, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example 1:

Input: 2, [[1,0]] 
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished   
             course 0. So the correct course order is [0,1] .

Example 2:

Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [0,2,1,3]
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both     
             courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. 
             So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .

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.

十分钟尝试

之前做过I的题目,是判断是否有循环依赖,是否能完成,本质就是拓扑排序,判断是否是一个DAG有向无环图的问题。

这个题目是需要输出序列,可以顺利完成的序列。我们可以把依赖关系看成一个有向图,因为可以输出结果,所以给定的序列一定没有环。现在的问题是输出这个序列,那么我们就用拓扑排序的DFS或者BFS处理。我习惯用BFS处理。先找遍历,各个节点的入度存入indegree数组,然后入度为0加入队列,同时所有子节点入度减去1,如果子节点入度为0,也加入队列,循环直到队列为空。输出的序列反序就是所求,add(0,element)就可以,不用单独排序。

但是发现结果是需要数组,不是queue,为了不再转化,所以定义一个数组,在BFS的时候添加元素到数组,注意从尾部开始。索引index最后重要的作用来判断是否进行了BFS,是否无环,因为如果有环,无法完全输出,index最后不会为0,此时输出int[0].

之前的算法判断indegree是否都为0,那是因为需要判断是否有环,如果有环就不全部为0.这个题目也可以,如果有环返回int[0],如果没有环,返回result。但是我们这里用index判断输出的数字个数是否是全部,都可以。详见另外一个题目:

https://blog.csdn.net/hanruikai/article/details/85629425

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int index=numCourses;
        int[] result=new int[numCourses];
        int[] indegree=new int[numCourses];
        if(numCourses==0){
            return result;
        }
        //计算各个入度
        for(int i=0;i<prerequisites.length;i++){
            indegree[prerequisites[i][1]]++;
        }
        //寻找入度为0的,入queue
        Deque  queue=new LinkedList();
        for(int i=0;i<indegree.length;i++){
            if(indegree[i]==0){
                //第二次写错了,应该是i
                 queue.add(i);
            }
        }
        //遍历队列如果不为空
        while(!queue.isEmpty()){
            int curr=(Integer)queue.poll();
             result[--index]=curr;
            //处理所有子,所有子入度减去1
            for(int i=0;i<prerequisites.length;i++){
                if(prerequisites[i][0]==curr){
                    indegree[prerequisites[i][1]]--;
                    if(indegree[prerequisites[i][1]]==0){
                        queue.add(prerequisites[i][1]);
                    }
                }
            }
        }
        //如果无环,能输出,最后index==0,否则输出一部分或者完全没有输出序列
        if(index!=0){
            return new int[0];
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/86065005