Leetcode:210. 课程表 II

Leetcode:210. 课程表 II

题目描述

现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。

可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

示例 1:

输入: 2, [[1,0]] 
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入: 4, [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
     因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。

说明:

输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
你可以假定输入的先决条件中没有重复的边。

提示:

这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。
通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。
拓扑排序也可以通过 BFS 完成。

思路

思路1 BFS

以依赖前置课程数为零的课程开始BFS,按照这个顺序修完所有课程并记录,同时记录所有的课程

思路2 DFS

类似与课程表LC207//TODO

代码

代码1

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] result = new int[numCourses];
        int[] depNum = new int[numCourses];
        List> afters = new ArrayList<>();
        for(int i = 0; i < numCourses; i++){
            afters.add(new ArrayList());
        }
        for(int[] pres: prerequisites){
            afters.get(pres[1]).add(pres[0]);
            depNum[pres[0]] += 1;
        }
        Queue queue = new LinkedList<>();
        for(int i = 0; i < numCourses; i++){
            if (depNum[i] == 0){
                queue.offer(i);
            }
        }
        // System.out.printf("%d\n", queue.size());
        int getIndex = 0;
        while(!queue.isEmpty()){
            int getNum = queue.remove();
            result[getIndex++] = getNum;
            for(int after: afters.get(getNum)){
                depNum[after] -= 1;
                if (depNum[after] == 0){
                    queue.offer(after);
                }
            }
        }
        return  getIndex == numCourses ? result: new int[0];
    }
}

复杂度分析

思路1时间复杂度

$O(V+E)$,所有的课程数目和依赖关系

思路1空间复杂度

$O(V+E)$


文章作者: 小风雷
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小风雷 !
评论
 上一篇
Leetcode:136. 只出现一次的数字 Leetcode:136. 只出现一次的数字
Leetcode:136. 只出现一次的数字题目描述给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 示例 1:
2020-04-30
下一篇 
Leetcode:207. 课程表 Leetcode:207. 课程表
[Leetcode: 207.课程表]题目描述你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配
2020-04-29
  目录