返回
征服 LeetCode 210:课程表 II 的妙招
前端
2023-12-31 20:36:46
导语
踏入 LeetCode 210 的殿堂,我们踏上了一段智力探险之旅。课程表 II 问题看似复杂,但只要掌握拓扑排序的真谛,就能轻松驾驭。本文将为你揭开拓扑排序的神秘面纱,助你征服 LeetCode 210 的挑战。
拓扑排序:拨开迷雾见彩虹
拓扑排序是一种算法,它对有向无环图(DAG)进行排序。DAG 中的节点表示任务,而边表示任务之间的依赖关系。拓扑排序的目的是找到任务的执行顺序,确保所有依赖关系都得到满足。
拓扑排序的实现通常采用深度优先搜索(DFS)。DFS 从一个起始节点开始,沿着所有可能的路径探索图,直到访问所有节点。在探索过程中,我们记录每个节点的入度,即指向该节点的边的数量。
算法流程:循序渐进,巧解难题
LeetCode 210 课程表 II 的解决方法如下:
- 构建邻接表: 根据给定的先修课程关系,创建邻接表来表示图。
- 计算入度: 初始化一个数组,记录每个课程的入度。
- 拓扑排序: 使用 DFS 从入度为 0 的课程开始,依次探索图,并更新课程的入度。
- 结果输出: 将按拓扑顺序访问的课程输出为最终结果。
实例解析:拨云见日,豁然开朗
考虑以下示例:
numCourses = 4
prerequisites = [[1,0],[2,0],[3,1],[3,2]]
根据给定的先修课程关系,我们可以构建邻接表:
graph = {
0: [1],
1: [2],
2: [3],
3: []
}
计算每个课程的入度:
indegree = [1, 1, 1, 0]
从入度为 0 的课程 3 开始 DFS:
- 访问课程 3,并将其从图中删除。
- 更新其他课程的入度:课程 2 的入度 -1。
重复上述步骤,直到所有课程都被访问:
访问顺序:3 -> 2 -> 1 -> 0
最终结果为:
[3, 2, 1, 0]
循环检测:警惕陷阱,规避风险
在进行拓扑排序时,我们需要警惕循环检测。如果图中存在环,则不存在拓扑顺序。我们可以通过记录 DFS 访问过的节点来检测循环。如果发现某个节点再次被访问,则说明存在环。
代码实现:一览无余,胜券在握
def findOrder(numCourses, prerequisites):
# 构建邻接表
graph = {i: [] for i in range(numCourses)}
for pair in prerequisites:
graph[pair[1]].append(pair[0])
# 计算入度
indegree = [0] * numCourses
for pair in prerequisites:
indegree[pair[0]] += 1
# 拓扑排序
result = []
queue = [i for i in range(numCourses) if indegree[i] == 0]
while queue:
course = queue.pop(0)
result.append(course)
for next_course in graph[course]:
indegree[next_course] -= 1
if indegree[next_course] == 0:
queue.append(next_course)
# 循环检测
if len(result) != numCourses:
return []
return result
总结
通过拓扑排序,我们可以轻松解决 LeetCode 210 课程表 II 问题。掌握拓扑排序的原理和实现方法,是算法学习中的重要一步。不断探索算法的世界,你会发现编程的魅力无穷。
致谢
感谢您的关注和支持。期待与您继续探索算法的奥秘,共创技术新篇章。