当前位置: 首页 > news >正文

LeetCode 210 课程表 II | 拓扑排序详解(C语言实现)

难度:中等
标签:图论、拓扑排序、BFS、DFS

题目描述

现在你总共有numCourses门课程需要选,记为0numCourses - 1。给你一个数组prerequisites,其中prerequisites[i] = [ai, bi],表示在选修课程ai前必须先完成课程bi

请你返回一个可行的课程学习顺序。如果不存在这样的顺序(存在环),返回空数组。

示例:

输入: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] 输出: [0,2,1,3] 解释: 学习课程 3 需要先学课程 1 和课程 2,而课程 1 和 2 都要在课程 0 后。

解题思路

这题是经典的拓扑排序问题

  1. 建图:将课程和先修关系建成有向图。

  2. 统计入度:每门课程的入度表示它的先修课程数量。

  3. BFS 遍历

    • 将入度为 0 的课程加入队列。

    • 每次出队一个课程,加入结果数组。

    • 遍历其邻接点,入度减 1,如果入度为 0,加入队列。

  4. 判断环

    • BFS 后,如果结果数组长度 != numCourses,则说明存在环,返回空数组。

  5. 返回拓扑序

    • BFS 遍历完,结果数组即为合法的课程顺序。

这种方法叫做Kahn 算法,时间复杂度为 O(V + E)。


C语言代码实现(BFS)

#include <stdio.h> #include <stdlib.h> /** * Note: The returned array must be malloced, assume caller calls free(). */ int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize) { // 邻接表 int** graph = (int**)malloc(sizeof(int*) * numCourses); int* graphColSize = (int*)calloc(numCourses, sizeof(int)); for (int i = 0; i < numCourses; i++) { graph[i] = (int*)malloc(sizeof(int) * prerequisitesSize); } // 入度数组 int* indegree = (int*)calloc(numCourses, sizeof(int)); // 建图 + 统计入度 for (int i = 0; i < prerequisitesSize; i++) { int a = prerequisites[i][0]; int b = prerequisites[i][1]; graph[b][graphColSize[b]++] = a; indegree[a]++; } // 队列 int* queue = (int*)malloc(sizeof(int) * numCourses); int front = 0, rear = 0; // 入度为0入队 for (int i = 0; i < numCourses; i++) { if (indegree[i] == 0) { queue[rear++] = i; } } // 结果数组 int* res = (int*)malloc(sizeof(int) * numCourses); int count = 0; // BFS while (front < rear) { int cur = queue[front++]; res[count++] = cur; for (int i = 0; i < graphColSize[cur]; i++) { int next = graph[cur][i]; indegree[next]--; if (indegree[next] == 0) { queue[rear++] = next; } } } if (count != numCourses) { *returnSize = 0; return (int*)malloc(0); } *returnSize = numCourses; return res; }

思路分析

  1. 建图
    将先修关系[ai, bi]转化为有向边bi -> ai

  2. 入度统计
    入度数组indegree[i]表示课程i还有多少先修课程未完成。

  3. BFS 拓扑排序

    • 队列存入度为 0 的课程。

    • 每次出队,加入结果数组。

    • 遍历出队课程的邻接课程,将入度减 1,若为 0 则入队。

  4. 检测环

    • 如果 BFS 后结果数组长度不等于课程总数,说明图中存在环,返回空数组。


时间复杂度与空间复杂度

  • 时间复杂度:O(V + E)

    • V:课程数量

    • E:先修关系数量

  • 空间复杂度:O(V + E)

    • 存图 + 入度数组 + 队列 + 结果数组


总结

  • 这类课程安排问题本质上是有向图的拓扑排序

  • 面试中可熟练使用BFS(Kahn 算法)DFS 拓扑排序(带环检测)

  • 对于多解情况,返回任意合法拓扑序即可。


http://www.jsqmd.com/news/616614/

相关文章:

  • Swoole 5.0适配踩坑实录,深度解析协程生命周期变更、内存管理新规与RPC协议不兼容问题
  • OpenClaw+Qwen3-14B内容工厂:自动生成技术博客与SEO优化
  • VibeVoice实时语音合成实战:25种音色一键切换,打造多语言语音助手
  • nanobot超轻量级AI助手部署实测:快速体验Qwen3-4B模型的智能回复
  • [具身智能-314]:大语言模型处理文本的全过程
  • 镜像视界VS 专家 :空间计算系统最刁钻10问 + 答案
  • 一键部署实时口罩检测-通用:基于Gradio的交互式Web界面快速上手
  • Lychee-Rerank安全加固指南:防止注入攻击与数据泄露
  • Fish-speech-1.5多语言支持实战:13种语言的语音合成技巧
  • 2026年12VDC通讯设备电磁开关/家电用电磁开关多家厂家对比分析 - 品牌宣传支持者
  • 镜像视界数字孪生空间系统:二轮追问反杀清单
  • 5分钟玩转像素语言·跨维传送门:腾讯混元引擎翻译工具实测
  • Ostrakon-VL 终端 Anaconda 虚拟环境管理:多项目 Python 依赖隔离指南
  • Chord实战:用视频分析工具制作智能安防系统,自动检测异常行为
  • 晶振到底是啥?为什么有26M/52M/25M/12M/32.768K?”一口气讲透(工程师秒懂版)
  • 2026年口碑好的汽车电磁开关/新能源电磁开关/通讯设备电磁开关主流厂家对比评测 - 品牌宣传支持者
  • KOOK艺术馆GPU优化:BF16精度下色彩饱和度保持与灰阶过渡实测
  • VibeVoice多场景应用案例:有声读物生成、无障碍阅读工具、IVR系统
  • 优选算法的层序之径:队列专题
  • OpenClaw技能组合方案:千问3.5-27B+OCR实现证件信息提取
  • Gemma-3-12b-it+OpenClaw内容处理:从资料收集到草稿生成全流程
  • YOLO12 WebUI边缘计算部署:低延迟实时检测方案
  • 2026年OptoCraft波前探测器选型推荐榜:Trim200离子束刻蚀机、Essent Optics分光光度计选择指南 - 优质品牌商家
  • PyTorch 2.8镜像部署YOLOv5目标检测模型:环境配置与推理优化
  • 从“人海战术”到“算法军团”:TVA引发的劳动力革命(4)
  • 幻境·流金多模态潜力:结合CLIP文本对齐实现高精度意合生成
  • FaceRecon-3D视觉特效实战:影视级数字人快速生成
  • AI产品经理逆袭指南:从技术小白到行业专家,这份学习地图请收好!
  • 2026年16A家电继电器/工控继电器/大电流继电器/通讯继电器公司对比推荐 - 品牌宣传支持者
  • Qwen3-0.6B-FP8一键部署Java面试题智能解析系统