210-Course Schedule II

【题目】

  你有n门课程需要完成,记为0到n-1。

      有些课程需要先完成预备课程,例如你在完成课程0前需要先完成课程1,记为对[0,1]。

    假如给定了课程总数以及所有预备关系对,返回完成所有课程的序列。

      可能有多个正确序列,你需要返回其中一种。如果不能完成所有课程,就返回空数组。

      举例:

      2 , [[1,0]]

  需要完成2门课程。 完成课程1前需要先完成课程0。所以正确的序列为[0,1]

      4 , [[1,0],[2,0],[3,1],[3,2]]

      有4门课程需要完成。完成课程3前需要先完成课程1和课程2,,完成课程1和课程2前都需要先完成课程0

      所以一个正确的序列为[0,1,2,3],另一个正确的序列为[0,2,1,3]。

【分析】

      1 . 与Course Schedule的解题方式一样,只是在找入度为0的点是记录节点

【算法实现】

public class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List<Set<Integer>> ls = new ArrayList<Set<Integer>>();
        for(int i=0; i<numCourses; i++) {
            ls.add(new HashSet<Integer>());
        }
        
        for(int i=0; i<prerequisites.length; i++) {
            ls.get(prerequisites[i][1]).add(prerequisites[i][0]);
        }
        
        int[] preNum = new int[numCourses];
        for(int i=0; i<numCourses; i++) {
            Iterator<Integer> it = ls.get(i).iterator();
            while(it.hasNext()) {
                preNum[it.next()]++;
            }
        }
        
        int[] res = new int[numCourses];
        for(int i=0; i<numCourses; i++) {
            int j;
            for(j=0; j<numCourses; j++) {
                if(preNum[j]==0) {
                    res[i]=j;
                    break;
                }
            }
            if(j==numCourses)
                return new int[0];
            preNum[j]=-1;
            
            Set<Integer> set = ls.get(j);
            Iterator<Integer> it = set.iterator();
            while(it.hasNext()) {
                preNum[it.next()]--;
            }
        }
        return res;
    }
}
原文地址:https://www.cnblogs.com/hwu2014/p/4519212.html