天题系列: 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();
            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;

    }
}

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;
     }
}
时间: 2024-09-15 01:35:17

天题系列: Course Schedule I的相关文章

微软100题系列之-----设计包含min函数的栈

题意: 定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素. 要求函数min.push 以及pop 的时间复杂度都是O(1). 思路:定义两个栈,一个用来记录数据的插入和删除,一个用来存储最小值的变化 代码如下: template <class T> class Stack { public: Stack(int len=100); T Min(); T Pop(); void Push(T val); private: T top1,top2; T *stack1,*stack

软考培训 | 根据2016新教程改版的百题系列完成改版工作

攻克要塞之考前100题系列完成改变工作. 两本书籍,<攻克要塞百题系列 系统集成项目管理工程师考前冲刺100题 第二版> <攻克要塞百题系列 信息系统项目管理师考前冲刺100题> 其中,中级系列用书根据2016新版教程和考纲进行了内容调整. 预计9月底上市发行! 本书配套的视频将于下半年在51cto视频网站发行.

微软面试100题系列算法心得

微软100题系列地址 答案地址 谓之随笔,当是自己在练习此类算法的一些想法,一些心得,一些领悟,一些借鉴,当自引用之时,会附上相应的链接! 题:把二元查找树转变成排序的双向链表(树) 描述:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 思维过程[个人思维]: 1. 二元查找树是指在任何结点看来,它的左子树上的值要少于当前结点的值,而它的右子树上的值要大于当前结点的值,对于等于的值那就看自己的原则放左子树还是右子树. 2. 关于树的算法必

hdu5017:补题系列之西安网络赛1011

补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为min(a,b,c) 所以我们需要把原方程化为标准型. 这时候线代就排上用场了,注意到原方程是一个二次型. 化为标准型 1/(k1)*x^2+1/(k2)*y^2+1/(k3)*z^2=1 后  min(k1,k2,k3)即为答案 而这里的1/k1,1/k2,1/k3 就是二次型矩阵的特征值 如何求特

ACdream oj C - 神奇的%系列一 (水题系列--略坑)

 C - 神奇的%系列一 Time Limit: 6000/3000 MS (Java/Others)      Memory Limit: 65536/32768 KB (Java/Others) Submit Status Problem Description 在计算机的世界里,%不是百分比,而是除法取余哟! 比如: 4 % 2 = 0 5 % 3 = 2 给你 2<=N<=100000 个数,a[1],a[2]...a[i]...a[n]. 其中:1<=a[i]<=10

nyoj 1208——水题系列——————【dp】

水题系列 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述     给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权值大的情况下,问你最多能走几条边? 输入 首先一个n和m,分别表示点的数目和边的数目接下来m行,每行三个值x,y,val,表示x到y有路,其权值为val.(1<n,m,val<10^5,0<x,y<=n) 输出 输出最多有的边的数目 样例输入 3 3 1 2 1 2 3 1 3 1 1 6

LCT男人八题系列

楼教的男人八题名气甚大,今天做了一道感觉还是涨了不少姿势的,然而估计之后的每道题都要看题解吧,姑且先记录一下.以后再做再更 1737 Connected Graph 1100 [email protected] 1738 An old Stone Game 407 [email protected] 1739 Tony's Tour 671 [email protected] 1740 A New Stone Game 2240 [email protected] 1741 Tree 1728

微软面试100题系列:字符串匹配算法,查找包含字符集的子串

觉得这题挺有意思,看了别的博客,找到了一种目前看来还不错的算法,为强化理解,就写了下来. 题目意思: 实现一个挺高级的字符匹配算法: 给一串字符串,要求找到符合要求的字符串,例如对于目的串:123,那么给定字符串中诸如1******3*****2,12******3这些形式的子串都要找出来,即子串中含有目的串的所有字符,输出所有符合条件的字符串,并求出最短子串 .类似于和谐系统. 例如:假如目的串为:"423",输入长字符串为:"4fsdfk2jfl3fd2jfksd3j4d

天题系列: LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.set(