返回

Python 版 leetcode 210. Course Schedule II 中课程顺序的拓扑排序法

后端

导读

leetcode 210. Course Schedule II 这道题目的目的是找到所有可行的课程顺序,以便学生能够按照该顺序完成所有课程而不会出现冲突。解决这个问题的一种有效方法是使用图论中的拓扑排序算法,而 BFS(广度优先搜索)算法就是一种常用的拓扑排序算法。

BFS 算法的要点

BFS 算法是解决图论问题的经典算法之一,具有广度优先的思想和先进先出(FIFO)的策略。在 BFS 算法中,需要使用队列来存储需要访问的节点,并依次访问队列中的节点,直到队列为空,即整个图中所有节点都被访问到了。

BFS 算法的要点在于,它每次都从队列中选择一个节点进行访问,然后将该节点的所有相邻节点加入队列中,直到队列中所有的节点都被访问完毕。这样,BFS 算法就能遍历整个图,并获得图中所有节点的访问顺序。

利用 BFS 算法进行拓扑排序

在 leetcode 210. Course Schedule II 这道题中,我们可以将课程看作节点,将课程之间的依赖关系看作边。这样,我们就可以将课程表表示成一个有向无环图(DAG)。

利用 BFS 算法可以对 DAG 进行拓扑排序,即找到一个线性序列,使得对于任意两门课程 A 和 B,如果 A 是 B 的先修课程,那么 A 在序列中一定排在 B 之前。

具体步骤如下:

  1. 将所有课程放入队列中。
  2. 从队列中取出一个课程,并将其添加到结果列表中。
  3. 找到该课程的所有后继课程,并将它们加入队列中。
  4. 重复步骤 2 和 3,直到队列为空。

经过以上步骤,我们就可以得到一个拓扑排序的结果。

Python 代码示例

from collections import defaultdict, deque

def findOrder(numCourses, prerequisites):
  """
  :type numCourses: int
  :type prerequisites: List[List[int]]
  :rtype: List[int]
  """
  # 构建邻接表
  graph = defaultdict(list)
  in_degree = [0] * numCourses

  for course, prereq in prerequisites:
    graph[prereq].append(course)
    in_degree[course] += 1

  # 将入度为 0 的课程放入队列
  queue = deque([i for i in range(numCourses) if in_degree[i] == 0])

  # 进行 BFS
  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) == numCourses:
    return result
  else:
    return []

# 测试
numCourses = 4
prerequisites = [[1,0],[2,0],[3,1],[3,2]]
print(findOrder(numCourses, prerequisites))

总结

本文介绍了如何使用 Python 和 BFS 算法解决 leetcode 210. Course Schedule II 这道题目,并详细讨论了如何利用 BFS 算法来实现课程顺序的拓扑排序。拓扑排序算法在实际场景中有很多应用,例如项目管理、任务调度等。掌握拓扑排序算法对于解决此类问题非常有帮助。