大厂面试题详解:安排课程

简介: 大厂面试题详解:安排课程

你需要去上n门九章的课才能获得offer,这些课被标号为 0 到 n-1 。
有一些课程需要“前置课程”,比如如果你要上课程0,你需要先学课程1,我们用一个匹配来表示他们: [0,1]
给你课程的总数量和一些前置课程的需求,返回你为了学完所有课程所安排的学习顺序。
可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

在线评测地址:领扣题库官网

例1:
输入: n = 2, prerequisites = [[1,0]] 
输出: [0,1]
例2:
输入: n = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] 
输出: [0,1,2,3] or [0,2,1,3]

解题思路

对于两门课之间的约束关系,很容易联想到图,我们可以将课抽象为节点,将约束抽象为一条有向边,可以用有向图的相关算法解决问题。拓扑排序正好可以解决这一问题。

算法:拓扑排序

一个合法的选课序列就是一个拓扑序,拓扑序是指一个满足有向图上,不存在一条边出节点在入节点后的线性序列,如果有向图中有环,就不存在拓扑序。可以通过拓扑排序算法来得到拓扑序,以及判断是否存在环。

拓扑排序步骤:

1.建图并记录所有节点的入度。
2.将所有入度为0的节点加入队列。
3.取出队首的元素now,将其加入拓扑序列。
4.访问所有now的邻接点nxt,将nxt的入度减1,当减到0后,将nxt加入队列。
5.重复步骤3、4,直到队列为空。
6.如果拓扑序列个数等于节点数,代表该有向图无环,且存在拓扑序。

复杂度分析

设课程数,即图的节点数为V。
约束数量,即图的边数为E。
时间复杂度O(V + E)

  • 建图,扫描一遍所有的边O(E)。
  • 每个节点最多入队出队1次,复杂度O(V)。
  • 邻接表最终会被遍历1遍,复杂度O(E)。
  • 综上,总复杂度为O(V + E)。
    空间复杂度O(V + E)
  • 邻接表占用O(V + E)的空间。
  • 队列最劣情况写占用O(V)的空间。
  • 综上,总复杂度为O(V + E)。
public class Solution {
    /*
     * @param numCourses: a total of n courses
     * @param prerequisites: a list of prerequisite pairs
     * @return: the course order
     */
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List[] graph = new ArrayList[numCourses];
        int[] inDegree = new int[numCourses];
        
        for (int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList<Integer>();
        }
        
        // 建图
        for (int[] edge: prerequisites) {
            graph[edge[1]].add(edge[0]);
            inDegree[edge[0]]++;
        }
        
        int numChoose = 0;
        Queue queue = new LinkedList();
        int[] topoOrder = new int[numCourses];
        
        // 将入度为 0 的编号加入队列
        for(int i = 0; i < inDegree.length; i++){
            if (inDegree[i] == 0) {
                queue.add(i);
            }
        }
        
        while (! queue.isEmpty()) {
            int nowPos = (int)queue.poll();
            topoOrder[numChoose] = nowPos;
            numChoose++;
            // 将每条边删去,如果入度降为 0,再加入队列
            for (int i = 0; i < graph[nowPos].size(); i++) {
                int nextPos = (int)graph[nowPos].get(i);
                inDegree[nextPos]--;
                if (inDegree[nextPos] == 0) {
                    queue.add(nextPos);
                }
            }
        }
        
        if (numChoose == numCourses)
            return topoOrder;
        return new int[0];
    }
}

更多题解参考:九章官网Solution

相关文章
|
7月前
|
缓存 算法 网络协议
Android面试回忆录移动应用开发专业核心课程
Android面试回忆录移动应用开发专业核心课程
|
4月前
|
人工智能 大数据 云计算
开启第二增长曲线!副业必备6000+课程、免费算力、编程实践助你飞速成长!
阿里云为高校学生提供全方位学习计划,含6000+免费精品课程与自测题,及免费在线编程练习。学生可免费获2.68亿小时算力,包括云服务器ECS、对象存储OSS等资源。同时,参与阿里云天池竞赛赢取高额奖金,并通过训练营获得实践经验和证书。借助这些资源,学生能紧跟信息化与AI潮流,为职业发展奠定坚实基础。
101 2
|
Java 程序员
第二季:0本课程前提要求和说明【Java面试题】
第二季:0本课程前提要求和说明【Java面试题】
93 0
|
SQL 程序员
【Sql Server】基础面试题解答之查询每门课程都及格的学生名称
1)查询每门课程都及格的学生名称 2)分组概念的使用
317 0
【Sql Server】基础面试题解答之查询每门课程都及格的学生名称
|
JavaScript 前端开发
如何在编程面试中脱颖而出——21 个解决问题的课程
如何在编程面试中脱颖而出——21 个解决问题的课程
107 0
|
Java Spring
《云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧》电子版地址
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧
120 0
《云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧》电子版地址
|
NoSQL 前端开发 Java
MongoDB与Java 经典面试题、课程,好资源值得收藏
Java、Spring Boot、MongoDB面试题、如果学习好MongoDB?如何拿高薪?阿里巴巴云栖社区整理了MongoDB与Java 经典面试题、课程,好资源值得收藏,陆续更新中。
7890 0
|
NoSQL Java Spring
【直播回顾】云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧
修炼Java,面试名企!本次课程,一起总结最新的Java Spring Boot 2.0面试题,以及阿里巴巴的招聘岗位,内推信息、面试技巧,最新的行业招聘信息。
2839 0
【直播回顾】云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
18天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?