返回
初探 LeetCode 207:巧用拓扑排序算法,叩开课程表之门
前端
2023-10-06 17:01:18
课程表问题剖析
课程表问题是一个经典的图论问题,在现实生活中有着广泛的应用。设想你是一名学生,需要在本学期选修多门课程。每门课程都有其先修课程,即必须在学习该课程之前先完成这些先修课程。你的任务是安排一个合理的课程表,使你能够在满足先修课程要求的前提下,顺利完成所有课程。
拓扑排序算法简介
拓扑排序算法是一种用于处理有向无环图(DAG)的算法。DAG 是一种特殊类型的图,其中不存在任何环路。拓扑排序算法的目的是将 DAG 中的顶点按一定的顺序排列,使得对于任何一条有向边 (u, v),顶点 u 总是在顶点 v 之前出现。
拓扑排序算法的基本思想是:从 DAG 中找出所有入度为 0 的顶点,即没有其他顶点指向它们的顶点。然后将这些顶点放入一个队列中,并从队列中逐个取出顶点。对于每个取出的顶点,我们将其所有出边指向的顶点的入度减 1。如果某个顶点的入度变为 0,则将其加入队列中。重复这一过程,直到队列为空或 DAG 中的所有顶点都被加入队列为止。
课程表问题的拓扑排序解法
课程表问题可以抽象为一个 DAG,其中顶点代表课程,有向边代表先修课程关系。拓扑排序算法可以帮助我们找到一个合理的课程安排顺序。
具体步骤如下:
- 将所有课程顶点放入一个集合中。
- 对于每个课程顶点,计算其入度。
- 将所有入度为 0 的课程顶点放入一个队列中。
- 从队列中逐个取出课程顶点。
- 对于每个取出的课程顶点,将其所有出边指向的课程顶点的入度减 1。
- 如果某个课程顶点的入度变为 0,则将其加入队列中。
- 重复步骤 4 至 6,直到队列为空或所有课程顶点都被加入队列为止。
代码实现
def find_order(num_courses, prerequisites):
"""
:type num_courses: int
:type prerequisites: List[List[int]]
:rtype: List[int]
"""
# 构建邻接表
graph = {}
for u, v in prerequisites:
if u not in graph:
graph[u] = []
graph[u].append(v)
# 计算每个课程的入度
in_degree = [0] * num_courses
for u in graph:
for v in graph[u]:
in_degree[v] += 1
# 将入度为 0 的课程放入队列中
queue = []
for i in range(num_courses):
if in_degree[i] == 0:
queue.append(i)
# 拓扑排序
result = []
while queue:
u = queue.pop()
result.append(u)
if u in graph:
for v in graph[u]:
in_degree[v] -= 1
if in_degree[v] == 0:
queue.append(v)
# 检查是否所有课程都被安排
if len(result) == num_courses:
return result
else:
return []
结语
在本文中,我们深入探究了 LeetCode 207 课程表的精妙解法,并详细介绍了拓扑排序算法的原理和应用。通过这个案例,我们不仅掌握了一门强大的算法,也锻炼了我们解决复杂问题的思维能力。在未来的编程之旅中,拓扑排序算法将成为我们解决更多问题的有力工具。