207-Course Schedule

【题目】

    你有n门课程需要上,几位0到n-1.

    有些课程需要一些预备课程,例如:上课程0前需要先上课程1,表示为对[0,1]

        假设给你所有课程和这些课程的对关系,有可能上完所有课程吗?

        举例:

        2 , [[1,0]]

        这有2个课程需要完成,完成课程1前需要完成课程0,所以是可能的。

        2 , [[1,0],[0,1]]

        这有2个课程需要完成,完成课程1前需要完成课程0,完成课程0前需要完成课程1,所以是不可能的。

【分析】

    1. 问题可以抽象为图的问题,就是判断图里是否存在环

        2. 解决方法:(拓扑排序),求出所有点的入度,循环遍历n(n为点个数)次,每一次循环里判断是否有点的入度  为0;若所有的点的入度都不为0,return false;

             反之,当前点的入度置为-1,进入下一次循环;跳出循环后,return true

【算法实现】

public class Solution {
    public boolean canFinish(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++) {
            Set<Integer> set = ls.get(i); 
            Iterator<Integer> it = set.iterator();
            while(it.hasNext()) {
                preNum[it.next()]++;
            }
        }
        
        for(int i=0; i<numCourses; i++) {
            int j;
            for(j=0; j<numCourses; j++) {
                if(preNum[j]==0)
                    break;
            }
            if(j==numCourses)
                return false;
            preNum[j] = -1;
            
            Set<Integer> set = ls.get(j);
            Iterator<Integer> it = set.iterator();
            while(it.hasNext()) {
                preNum[it.next()]--;
            }
        }
        return true;
    }
}

 

posted @ 2015-05-20 19:26  hwu_harry  阅读(120)  评论(0编辑  收藏  举报