返回

课程表 II 详解:解决课程顺序优化问题

闲谈

课程表 II 的问题如下:

给定一个由整数对组成的列表 courses,其中 courses[i] = [course_i, prerequisite_i],表示课程 course_i 的先修课程是 prerequisite_i。
您需要按照以下要求安排课程:

  • 每门课都必须在满足其所有先修课程的要求后才能开始学习。
  • 返回满足所有课程先修关系的有序课程表,如果不存在这样的课程表,则返回空列表。

解决方案

课程表 II 问题的核心在于如何处理课程之间的依赖关系,以生成一个满足所有先修课程要求的课程表。为了解决这个问题,我们可以使用广度优先搜索(BFS)算法。

广度优先搜索算法的基本思路是:

  1. 初始化一个队列 queue,将所有入度为 0 的课程入队。
  2. 重复以下步骤,直到队列为空:
    • 从队列中取出一个课程 course。
    • 将 course 标记为已学习。
    • 将所有以 course 为先修课程的其他课程的入度减 1。
    • 如果某个课程的入度变为 0,则将其入队。
  3. 如果队列中所有课程都已学习,则返回课程表。否则,返回空列表。

代码实现

from collections import deque
from typing import List

def findOrder(courses: List[List[int]]) -> List[int]:
    """
    :type courses: List[List[int]]
    :rtype: List[int]
    """
    # 初始化入度数组和邻接表
    in_degree = [0] * len(courses)
    graph = [[] for _ in range(len(courses))]
    for course, prerequisite in courses:
        in_degree[course] += 1
        graph[prerequisite].append(course)

    # 初始化队列
    queue = deque([course for course in range(len(courses)) if in_degree[course] == 0])

    # 广度优先搜索
    result = []
    while queue:
        course = queue.popleft()
        result.append(course)

        for next_course in graph[course]:
            in_degree[next_course] -= 1
            if in_degree[next_course] == 0:
                queue.append(next_course)

    # 检查是否有环
    if len(result) == len(courses):
        return result
    else:
        return []

时间复杂度分析

课程表 II 的时间复杂度为 O(V + E),其中 V 是课程的总数,E 是课程之间的依赖关系数。

空间复杂度分析

课程表 II 的空间复杂度为 O(V),因为我们需要存储入度数组、邻接表和队列。

总结

课程表 II 是一个经典的计算机科学问题,涉及课程安排和依赖关系。通过使用广度优先搜索算法,我们可以高效地解决这个问题,并生成一个满足所有课程先修关系的课程表。