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

别再死记硬背了!用Kahn算法搞定LeetCode 207课程表,保姆级C++代码逐行解析

从课程表到任务调度Kahn算法在LeetCode 207中的实战应用每次打开LeetCode看到那道课程表问题你是不是也感到一阵头疼先修课程、依赖关系、环状检测……这些概念堆在一起简直比大学选课系统还让人崩溃。但别担心今天我们就用Kahn算法来彻底解决这个难题让你在面试中遇到类似问题时能够游刃有余。1. 理解问题本质为什么课程表需要拓扑排序LeetCode 207题课程表描述的是这样一个场景你需要选修n门课程有些课程有先修要求比如必须先修完数学才能选物理。题目会给出课程总数和一系列先修关系对要求判断是否可能完成所有课程。这个问题本质上是一个有向无环图(DAG)的检测问题。我们可以把每门课程看作图中的一个节点而先修关系A→B则表示从A到B的一条有向边。如果这个图中存在环就意味着出现了循环依赖比如A需要BB需要CC又需要A这种情况下显然无法完成所有课程。拓扑排序正是解决这类依赖关系问题的利器。它能够将图中的节点线性排列保证对于任何有向边u→vu在排序中总是位于v的前面。Kahn算法作为拓扑排序的一种经典实现特别适合用来检测图中是否存在环。2. Kahn算法核心思想拆解Kahn算法的精妙之处在于它模拟了一个自然的过程不断移除当前没有前置依赖的节点。让我们用更直观的方式来理解它的三个核心步骤初始化阶段计算每个节点的入度有多少边指向它将所有入度为0的节点加入待处理队列处理阶段从队列中取出一个节点加入结果集移除这个节点将它所有邻居的入度减1如果某个邻居的入度因此变为0就把它加入队列检测阶段如果最终结果集包含所有节点说明拓扑排序成功否则说明图中存在环提示在实际编码中我们并不真的删除节点而是通过维护入度数组来模拟这个过程这样既高效又节省空间。3. 从理论到实践C实现详解现在让我们把这些概念转化为实际的代码。以下是解决LeetCode 207的完整C实现我们将逐行解析关键部分#include vector #include queue using namespace std; bool canFinish(int numCourses, vectorvectorint prerequisites) { // 构建邻接表和入度数组 vectorvectorint adj(numCourses); vectorint inDegree(numCourses, 0); for (auto edge : prerequisites) { adj[edge[1]].push_back(edge[0]); // edge[1]是前置课程指向edge[0] inDegree[edge[0]]; } // 初始化队列收集所有入度为0的节点 queueint q; for (int i 0; i numCourses; i) { if (inDegree[i] 0) { q.push(i); } } int count 0; // 记录已处理的课程数 while (!q.empty()) { int current q.front(); q.pop(); count; // 处理当前课程的所有后续课程 for (int neighbor : adj[current]) { if (--inDegree[neighbor] 0) { q.push(neighbor); } } } return count numCourses; }让我们分解这段代码的关键部分数据结构选择adj邻接表存储每个课程的后续课程列表inDegree记录每门课程的当前入度queue用于BFS遍历存储当前可修的课程构建图根据输入的先修关系构建邻接表和入度数组注意题目给出的边是[A,B]表示B→AB是A的先修核心算法流程初始化时收集所有入度为0的课程每处理一门课程就将其后续课程的入度减1当后续课程的入度变为0时加入队列环检测最终比较已处理课程数与总课程数如果相等说明无环否则存在环4. 算法优化与常见陷阱在实际面试中仅仅给出基础实现是不够的。我们需要考虑算法的优化空间和常见错误4.1 时间复杂度分析构建图O(E)其中E是边数先修关系对数初始化队列O(V)V是课程数BFS过程每个节点和边都被处理一次O(VE)总时间复杂度O(VE)这是最优的复杂度因为我们至少需要访问每个节点和边一次。4.2 空间复杂度分析邻接表O(VE)入度数组O(V)队列最坏情况下O(V)总空间复杂度O(VE)4.3 常见实现错误边方向混淆题目给出的边[A,B]表示要修A必须先修B容易错误地构建为A→B的关系实际上应该是B→A环检测不充分仅检查队列是否为空是不够的必须比较已处理课程数与总课程数不必要的复杂数据结构有些同学会使用复杂的图结构如邻接矩阵对于这个问题简单的邻接表就足够了4.4 实际面试中的扩展问题面试官可能会追问如果要求输出一个可行的修课顺序如何修改代码当存在多种可行顺序时如何保证输出某种特定顺序如字典序最小如果课程之间有优先级权重如何找到最优的修课顺序对于第一个问题我们只需要在出队列时记录顺序vectorint findOrder(int numCourses, vectorvectorint prerequisites) { // ...前面的图构建部分相同 vectorint result; while (!q.empty()) { int current q.front(); q.pop(); result.push_back(current); // ...后续处理相同 } return result.size() numCourses ? result : vectorint(); }5. 从LeetCode到现实拓扑排序的应用场景理解算法不能停留在做题层面让我们看看拓扑排序在真实世界中的应用课程安排系统正如LeetCode题目所示用于大学课程安排确保学生不会遇到无法满足的先修条件软件构建系统Makefile中的依赖关系解析确定源代码文件的编译顺序任务调度系统处理有依赖关系的任务例如数据处理流水线中某些任务必须在其他任务完成后才能开始事件处理系统确定事件的触发顺序确保前置事件先于后续事件处理包管理系统解决软件包安装时的依赖关系如apt-get、yum等工具的内部实现理解这些实际应用场景不仅能帮助你在面试中更好地解释算法也能让你在面对实际问题时更快地识别出适用的算法模式。

相关文章:

别再死记硬背了!用Kahn算法搞定LeetCode 207课程表,保姆级C++代码逐行解析

从课程表到任务调度:Kahn算法在LeetCode 207中的实战应用 每次打开LeetCode看到那道课程表问题,你是不是也感到一阵头疼?先修课程、依赖关系、环状检测……这些概念堆在一起,简直比大学选课系统还让人崩溃。但别担心,今…...

Original PIPE vs. Serdes PIPE: Understanding the Key Differences in PHY Interface Design

1. 从零理解PIPE接口:物理层设计的通用语言 第一次接触PIPE接口时,我完全被各种缩写搞晕了。直到在某个PCIe项目中被时序问题折磨了整整两周后,才真正明白这个接口的重要性。简单来说,PIPE(PHY Interface for PCI Expr…...

day23 模拟2

...

【单片机】内核中断及NVICPending

红色框住的是M3内核中断,青色框住的默认打开,不可关闭中断(除NMI外可屏蔽)。包括SysTick在内无需NVIC_EnableIRQ,也无需在中断处理函数里清标志位。NVIC_SetPendingIRQ和NVIC_ClearPendingIRQ基本用不到,任…...

终极指南:如何用Save Image as Type一键转换网页图片格式

终极指南:如何用Save Image as Type一键转换网页图片格式 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址: https://gitcode.com/gh_mirrors/sa/Sav…...

GStreamer性能优化指南:在Jetson TX2上实现4K视频低延迟处理(基于NVMM内存)

GStreamer性能优化指南:在Jetson TX2上实现4K视频低延迟处理(基于NVMM内存) 在嵌入式视觉和实时视频处理领域,NVIDIA Jetson TX2凭借其强大的GPU和专用硬件加速单元,成为工业级应用的理想选择。但要将这块开发板的性能…...

Protege新手避坑指南:搞懂‘类’、‘属性’和‘推理’到底怎么用(附常见错误排查)

Protege新手避坑指南:搞懂‘类’、‘属性’和‘推理’到底怎么用(附常见错误排查) 第一次打开Protege时,满屏的术语和复杂的界面可能会让你感到不知所措。作为一款强大的本体编辑工具,Protege确实有着陡峭的学习曲线。…...

SystemVerilog内存操作实战:手把手教你实现AXI VIP中的backdoor读写

SystemVerilog内存操作实战:AXI VIP中的backdoor读写技术解析 在硬件验证领域,AXI总线协议因其高性能和灵活性已成为行业标准。验证工程师经常需要与AXI VIP(Verification IP)交互,其中内存操作是最基础也最关键的环节…...

SpringBoot整合MQTT实战:手把手教你实现设备动态连接与主题订阅管理(附完整源码)

SpringBoot整合MQTT实战:动态连接与主题订阅管理的工程化实现 在物联网项目开发中,设备连接管理和消息路由的灵活性往往是系统设计的难点。想象这样一个场景:你的智慧农业系统需要随时接入新部署的土壤传感器,气象站设备可能因网…...

SpringBoot+Vue员工绩效系统实战:从数据库设计到权限控制的完整避坑指南

SpringBootVue员工绩效系统实战:从数据库设计到权限控制的完整避坑指南 在数字化转型浪潮下,企业绩效管理系统正从传统的Excel表格升级为智能化平台。本文将带您从零构建一个具备多维度考核、动态权限控制和可视化分析的绩效系统,重点解决实际…...

嵌入式 数据结构 线性表 学习笔记

线性表线性结构的特点是:1、存在唯一的一个被称作“第一个”的数据元素2、存在唯一的一个被称作“最后一个”的数据元素3、除第一个之外,集合中的每个元素均只有一个前驱4、除最后一个以外,集合中的每个数据元素均只有一个后继顺序表示和实现…...

Phi-4-Reasoning-Vision行业落地:教育领域图像题解与隐藏线索识别案例

Phi-4-Reasoning-Vision行业落地:教育领域图像题解与隐藏线索识别案例 1. 项目背景与价值 在教育领域,图像题解和隐藏线索识别一直是教学和考试中的难点。传统方法依赖人工标注和分析,效率低下且容易遗漏关键信息。Phi-4-Reasoning-Vision多…...

从RS485到TCP/IP:Modbus协议V1.1b3的三种组网方式对比(含WireShark抓包分析)

从RS485到TCP/IP:Modbus协议V1.1b3的三种组网方式深度实战解析 在工业自动化领域,Modbus协议已经服役超过40年,却依然保持着惊人的生命力。作为工程师,我们常常面临一个关键抉择:在RS485、Modbus和TCP/IP这三种主流组…...

【大模型工程实践③】RAG 基础架构与完整实现

【大模型工程实践③】RAG 基础架构与完整实现:从0到1跑通 作者:AI学习者 | 来源:大模型工程实践学习系列 | 更新:2026年3月 【理论要点速览】 学习本篇前,建议先掌握以下核心理论(点击跳转): ① 为什么需要RAG? ② RAG vs Fine-tuning vs Long Context的决策框架 ③ …...

高效对接Tiktok电商API:PHP开发者的一站式解决方案指南

高效对接Tiktok电商API:PHP开发者的一站式解决方案指南 【免费下载链接】tiktokshop-php Unofficial Tiktok Shop API Client in PHP. Use API version 202309 and later 项目地址: https://gitcode.com/gh_mirrors/ti/tiktokshop-php 在瞬息万变的电商生态中…...

【GitHub 加速计划】:解决智能家居插件获取难题的网络适配方案

【GitHub 加速计划】:解决智能家居插件获取难题的网络适配方案 【免费下载链接】integration 项目地址: https://gitcode.com/gh_mirrors/int/integration 在智能家居系统搭建过程中,插件获取往往是用户面临的首要障碍。许多优质的智能家居插件托…...

解锁TikTok电商API:PHP开发者的零门槛接入方案

解锁TikTok电商API:PHP开发者的零门槛接入方案 【免费下载链接】tiktokshop-php Unofficial Tiktok Shop API Client in PHP. Use API version 202309 and later 项目地址: https://gitcode.com/gh_mirrors/ti/tiktokshop-php 跨境电商API对接新选择&#xf…...

3D场景重建与实时渲染:XV3DGS-UEPlugin技术指南

3D场景重建与实时渲染:XV3DGS-UEPlugin技术指南 【免费下载链接】XScene-UEPlugin 项目地址: https://gitcode.com/gh_mirrors/xv/XScene-UEPlugin XV3DGS-UEPlugin是由XVERSE Technology Inc.开发的基于Unreal Engine 5的混合编辑插件,提供Gaus…...

MoMask终极指南:5分钟学会AI生成3D人体运动动画

MoMask终极指南:5分钟学会AI生成3D人体运动动画 【免费下载链接】momask-codes Official implementation of "MoMask: Generative Masked Modeling of 3D Human Motions (CVPR2024)" 项目地址: https://gitcode.com/gh_mirrors/mo/momask-codes 想…...

GCC编译选项详解与工程实践指南

GCC编译选项深度解析与工程实践指南1. 编译选项基础概念1.1 编译过程与选项作用GCC编译过程分为预处理、编译、汇编和链接四个阶段。编译选项通过控制这些阶段的行为,实现不同的编译目标:# 完整编译流程示例 gcc -E main.c -o main.i # 预处理 gcc -S…...

Dify私有化部署实战:如何在企业内网快速搭建AI开发平台(含Docker镜像打包技巧)

Dify私有化部署实战:企业内网AI开发平台搭建全攻略 1. 企业内网部署Dify的核心价值与挑战 在数字化转型浪潮中,越来越多的企业开始将AI能力纳入核心业务系统。Dify作为开源的大语言模型应用开发平台,其私有化部署方案尤其适合对数据安全有严…...

别再硬编码了!Qt QTabBar标签宽度自适应窗体的5种实战方案对比(附完整代码)

Qt QTabBar标签宽度自适应窗体的5种实战方案深度评测 每次看到Qt界面中那些挤在一起或稀疏分布的标签页,总让人想起超市货架上摆放不齐的商品——既影响美观又降低使用效率。作为中级Qt开发者,你一定遇到过这样的困境:当窗体尺寸变化时&#…...

如何实现Flomo到Obsidian的高效迁移与无缝衔接?一站式数据迁移工具全解析

如何实现Flomo到Obsidian的高效迁移与无缝衔接?一站式数据迁移工具全解析 【免费下载链接】flomo-to-obsidian Make Flomo Memos to Obsidian Notes 项目地址: https://gitcode.com/gh_mirrors/fl/flomo-to-obsidian 当你需要将积累已久的Flomo笔记迁移到Obs…...

SparkFun ICM-20948 Arduino库:DMP硬件协处理器深度实践指南

1. 项目概述SparkFun ICM-20948 Arduino Library 是面向 TDK InvenSense ICM-20948 九轴惯性测量单元(9DoF IMU)的官方 Arduino 封装库,专为 SparkFun 9DoF IMU Breakout - ICM-20948(Qwiic 接口版本,型号 SEN-15335&a…...

Agent 性能优化:降低 Token 消耗的 5 个技巧

Agent 性能优化:降低 Token 消耗的 5 个技巧系列文章: 《AI Agent 开发实战》第 7 期 难度等级: ⭐⭐⭐⭐ 预计耗时: 35 分钟🎯 本文目标 学会优化 AI Agent 性能: ✅ 减少 Token 消耗✅ 提高响应速度✅ 降…...

WebGL BIM可视化:浏览器端BIM解决方案的技术实践与行业应用

WebGL BIM可视化:浏览器端BIM解决方案的技术实践与行业应用 【免费下载链接】xeokit-bim-viewer A browser-based BIM viewer, built on the xeokit SDK 项目地址: https://gitcode.com/gh_mirrors/xe/xeokit-bim-viewer 如何解决浏览器端BIM模型加载慢、操…...

Llama-3.2-3B效果体验:Ollama简单操作,产出专业级文案

Llama-3.2-3B效果体验:Ollama简单操作,产出专业级文案 1. 模型概览:小而精的文本生成专家 Llama-3.2-3B是Meta最新推出的轻量级语言模型,在3B参数规模下实现了接近大模型的文本生成质量。经过指令微调优化后,它在多语…...

打破数据标注瓶颈:Label Studio如何让AI训练效率提升300%?

打破数据标注瓶颈:Label Studio如何让AI训练效率提升300%? 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地址: https://gitcode.com/GitHub_Trending/la/labe…...

水库调度员必看:动态规划在月度发电计划中的5个避坑指南

水库调度员实战指南:动态规划在月度发电计划中的5个关键避坑策略 在水利工程领域,水库调度是一项集科学性、技术性和艺术性于一体的复杂工作。作为水库调度员,我们每天都在与时间、水量和电力需求进行着精妙的博弈。而动态规划作为一种强大的…...

YOLOv8目标检测新玩法:用VMamba替换C2f模块,我在DDSM医疗数据集上mAP涨到了0.724

YOLOv8与VMamba融合:医疗影像目标检测的突破实践 在医疗影像分析领域,目标检测技术正经历着从传统卷积神经网络到新型架构的转变。最近,我们将YOLOv8模型中的C2f模块替换为VMamba模块,在DDSM乳腺X光数据集上取得了mAP 0.724的显著…...