[Lintcode] Course Schedule

Description:

 

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, is it possible for you to finish all courses?

Example

Given n = 2, prerequisites = [[1,0]]
Return true

Given n = 2, prerequisites = [[1,0],[0,1]]
Return false

结题报告:

看到这种题就要想到这是个图的拓扑排序问题:基本思路就是先统计入度(indegree)然后把indegree从0开始搜索,看能不能走通。

但是这里面输入的东西又不是图,所以要构建一个图。构建图的方法我现在主要用两种:1,Map<node, neighbors<node>>:这里node可以用class node也可以用integer代替。2,ArrayList[ArrayList<Integer>] 这种时候是说node用0 - n-1的整数代表node,list表示有边的点的集合。

思路:

1,构建图。

2,统计所有点的入度。

3,找起点(入度=0)

4,BFS从入度0开始,按入度从小到大搜索,看能否把所有点搜索到。

全部搜索的到就是没有环的,不然就是有环的。

详情见代码:
public class Solution {
    /**
     * @param numCourses a total of n courses
     * @param prerequisites a list of prerequisite pairs
     * @return true if can finish all courses or false
     */
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if (numCourses == 0) {
            return true;
        }
        //这里不需要这个判断,这个判断是针对树的
        // if (prerequisites.length < numCourses - 1) {
        //     return false;
        // }
        /////////////////
        // calculate in-degree
        // build graph:这里用List做图是因为这里的用0--n-1 做node,可以与graph[i]
        //形成一一对应的pair关系,如果node点是其他string或者不是生序int就要用hash
        int[] indegree = new int[numCourses];
        List[] graph = new ArrayList[numCourses];
        // initial graph
        for (int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList<Integer>();
            //edges[i] = new ArrayList<Integer>();
        }
        //
        for (int i = 0; i < prerequisites.length; i++) {
            indegree[prerequisites[i][0]] ++;  
            // 计算入读时候要考虑题设,这里数组*第二位*才是前序课程
            graph[prerequisites[i][1]].add(prerequisites[i][0]);
            // build图的时候要考虑边的方向,这里是从前序课程->后续课程
        }
        // find start point :indegree == 0
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < indegree.length; i++) {
            if (indegree[i] == 0) {
                queue.offer(i);
            }
        }
        if (queue.size() == 0) {
            return false;
        }
        //bfs
        int count = 0;
        while (!queue.isEmpty()) {
            int course = queue.poll();
            count ++;
            for (int i = 0; i < graph[course].size(); i++) {
                int pointer = (int)graph[course].get(i);
                indegree[pointer] --;
                if (indegree[pointer] == 0) {
                    queue.add(pointer);
                }

                // if (indegree(pointer) == 0) {
                //     queue.offer(pointer);
                // }
            }
        }
        // output result
        return (count == numCourses);
    }
}
View Code

 

posted @ 2017-08-18 03:16  Tri_tri_tri  阅读(136)  评论(0)    收藏  举报