LeetCodeMEDIM篇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;
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章