天题系列: Course Schedule I

关键是想清楚每一个课 A 都对应一个neighbor list,即是 A的后续课程 set{b,c,d,...}

讲解 http://blog.csdn.net/dm_vincent/article/details/7714519

每次是剪掉一个“入点”,即non-pre的初始课,然后剪掉它对应的edge,如果图上再无edge,则说明这个j为入点的  topological sub graph没有circle,则OK,有circle则return false

topological sort BFS 算法(图示 ref  http://www.cnblogs.com/skywang12345/p/3711494.html)

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        // BFS http://blog.csdn.net/ljiabin/article/details/45846837
        // 把入度为0 的点一个个删掉并减掉他们的出去边,最后如果还剩下 边, 则说明有circle
        List<Set> posts = new ArrayList<Set>() ; // 自行比较为啥不是hashmap, 因为每个course A 对应的是一个list set{b,c,d,e}
        
        for(int i=0; i<numCourses;i++){
            // establish neighbor list for each course
            posts.add(new HashSet<Integer>());
        }
       // for(int i=0; i<numCourses;i++){
        for(int i=0;i<prerequisites.length;i++){
            // add the neighbors to the list for each course
            posts.get(prerequisites[i][1]).add(prerequisites[i][0]);
        }
        int[] preNum = new int[numCourses];
        for(int i=0; i<numCourses;i++){
            // count the list' length for each course
            Set s = posts.get(i);
            Iterator<Integer> it = s.iterator(); // <Integer> 是为了it.next()得到的是int型,这样preNum[int]
            while(it.hasNext()){
                preNum[it.next()]++;
            }
        }
        for(int i=0; i<numCourses;i++){
            int j=0;
            for(;j<numCourses;j++){
                if(preNum[j]==0) break; // find the non-pre course,入点
            }
            if(j==numCourses) return false; // 没有入点,说明删了n圈之后还有剩余边,有circle!!
            preNum[j]= -1;      //删除这个点,其实不是很明白
            
            Set s= posts.get(j);
            Iterator<Integer> it = s.iterator();
            while(it.hasNext()){
                preNum[it.next()]--;
            }
        }
        return true;
        
    }
}

 简洁版本的bfs

ref

https://github.com/wjjal/LeetCode/blob/master/src/L207CourseSchedule.java

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if(numCourses==0 || prerequisites.length==0) return true;
        int can =0; // how many courses can be finished
        int[] cnt = new int[numCourses] ; // for each course, how many prerequisites
        LinkedList<Integer> st = new LinkedList<Integer>(); //   courses which need no prerequisites
        int m = prerequisites.length;
        for(int i=0; i<m; i++){
            cnt[prerequisites[i][0]]++;
        }
        for(int i=0; i< numCourses; i++){
            if(cnt[i]==0){
                can++;
                st.push(i);   
            }
        }
        while(!st.isEmpty()){
            int cur = st.pop();                // cur needs no prerequisites
            for(int i=0;i<m;i++){
                if(prerequisites[i][1]==cur){  // if pair-i's prerequiste is cur
                    if(--cnt[prerequisites[i][0]]==0){ // and if remove cur, can make pair-i's first class need no prerequisite
                        can++;
                        st.push(prerequisites[i][0]);
                    }
                }
            }
        }
        return can== numCourses? true: false;
    }
}

 

DFS 作法就是按照一个点,然后找到它的neighbor list, iterate其中每个点 dfs下去

        if(numCourses==0 || prerequisites.length==0) return true;
        if(prerequisites==null) return false;
        int[] visit = new int[numCourses];
        HashMap<Integer, ArrayList<Integer>> hm = new HashMap<Integer, ArrayList<Integer>>();
        for(int[] a:prerequisites ){
            if(hm.containsKey(a[1])){
                hm.get(a[1]).add(a[0]);
            }else{
                ArrayList<Integer> t = new ArrayList<Integer>();
                t.add(a[0]);
                hm.put(a[1],t);
            }
        }
        for(int i=0;i<numCourses;i++){
            if(!canFinDFS(visit, hm, i)){
                return false;
            }
        }
        return true;
    }
     public boolean canFinDFS(int[] visit, HashMap<Integer, ArrayList<Integer>> hm, int i){
         if(visit[i]==-1) return false;
         if(visit[i]==1) return true;
         visit[i]=-1;
         // do not forget to iterate the hm
         if(hm.containsKey(i)){
         for(int j: hm.get(i)){
             if(!canFinDFS(visit, hm, j))
                return false;
         }
         }
         visit[i]=1;
         return true;
     }
}

 

posted @ 2015-05-20 11:42  世界到处都是小星星  阅读(260)  评论(0编辑  收藏  举报