美文网首页
拓扑排序:207. 课程表(中等)

拓扑排序:207. 课程表(中等)

作者: 言的希 | 来源:发表于2021-04-16 14:58 被阅读0次

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

示例 1:

            输入:numCourses = 2, prerequisites = [[1,0]]

            输出:true

            解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

示例 2:

            输入:numCourses = 2, prerequisites = [[1,0],[0,1]]

            输出:false

            解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

解题思路:拓扑排序,这个问题等价于求有向图中是否存在循环。如果存在一个循环,则不存在拓扑序列,因此不可能修完所有课程。

拓扑排序方法:1.在有向图中任意选一个没有前驱的节点,(且输出);

                         2.从图中删除该顶点 以及 所有以它为尾的边;

                         3.重复12, 直至全部节点均已输出,或图中不存在无前驱的顶点为止。 

判断图节点是否有先驱节点,利用图节点的入度来计算,如果一个节点入度==0,则该节点没有前驱节点。

public boolean canFinish(int numCourses, int[][] prerequisites) {

        // 1.根据边的关系来构造图

        List<Integer>[] graph = new List[numCourses]; //构造邻接表来存储图

        for (int i=0; i<numCourses; i++) {

            graph[i] = new ArrayList<>();

        } 

        for(int[] pre : prerequisites) {

            graph[pre[1]].add(pre[0]);

        }

        // 2.创建入度表

        int[] inDegree = new int[numCourses];

        for (int i=0; i<numCourses; i++) {

            List<Integer> per = graph[i];

            for (int j : per) {

                inDegree[j] += 1;

            }

        }

        // 3.入度为0的节点入队列,然后删除这个节点 以及所有关系( 对应的节点的入度-1)

        Queue<Integer> queue = new LinkedList<>();

        for (int i=0; i<numCourses; i++) {

            if(inDegree[i] == 0){

                queue.offer(i);

            }

        }

        while(!queue.isEmpty()) {

            int temp = queue.poll();

            numCourses--; //删除temp节点后,节点总数-1

            for (int next : graph[temp]) {

                inDegree[next] -= 1; //对应的节点的入度-1

                if(inDegree[next] == 0) {

                    queue.offer(next);

                }

            }

        }

        return numCourses == 0; //判断是否把所有节点都删除了,是则代表无循环图,返回true

    }

相关文章

网友评论

      本文标题:拓扑排序:207. 课程表(中等)

      本文链接:https://www.haomeiwen.com/subject/klgclltx.html