算法日常・每日刷题--<BFS拓扑排序>4

LCR 113. 课程表 II - 力扣(LeetCde)

题目理解

总共有 numCourses 门课,编号0 ~ numCourses‑1prerequisites[i] = [a,b]学 a 课,必须先学 b 课

要求返回任意一个合法上课顺序

  • 存在拓扑序列(无环):返回上课顺序数组
  • 图有环(循环依赖,课学不完):返回空数组

和课程表 I 区别:课程表 I 只需要判断 true/false;本题需要把拓扑排序的序列输出出来。

核心思路 BFS 拓扑排序

  1. 建图(邻接表)b → a,b 上完之后才可以上 a;统计每门课的入度(还有几门先修没上完)
  2. 入度为 0 全部入队列:不需要先修、可以直接学的课程
  3. BFS 遍历
    • 取出队头课程,加入结果集合(代表这门课已经上完)
    • 把它所有后继课程入度减一(消除这门课带来的依赖)
    • 如果后继课程入度变成 0,说明它的全部先修课完成,入队列
  4. 最后判断
    • 如果结果数组长度等于总课程数:全部课都上完,直接返回结果
    • 长度不够:说明有环,返回空数组
cpp 复制代码
class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> edges(numCourses); // 临接表
        vector<int> in(numCourses,0);

        // 构建图
        for (auto e : prerequisites) {
            int a = e[0];
            int b = e[1];
            edges[b].push_back(a);
            in[a]++;
        }

        vector<int> ret;
        queue<int> q;
        for (int i = 0; i < numCourses; i++) {
            if (in[i] == 0) {
                q.push(i);
            }
        }

        while (q.size()) {
            int a = q.front();
            q.pop();
            ret.push_back(a);
            for (auto next : edges[a]) {
                // 将有关边的入度--
                in[next]--;
                if (in[next] == 0) {
                    q.push(next);
                }
            }
        }
        if (ret.size() == numCourses)
            return ret;
        else
            return {};
    }
};
相关推荐
不正经学生24 分钟前
C语言动态内存管理(上):堆上的自由与责任
c语言·开发语言·c++·算法·面试
伟大的车尔尼25 分钟前
贪心的概念
数据结构·算法·贪心
方方洛41 分钟前
vllm教程-00-前言与导读
人工智能·算法·vllm
IT毕设实战小研1 小时前
电影数据可视化推荐系统
大数据·后端·爬虫·python·算法·信息可视化·课程设计
且随疾风前行.1 小时前
从驱动来分析服务的添加过程
算法
CoderYanger1 小时前
A.每日一题:输入单词需要的最少按键次数 Ⅰ+Ⅱ
java·数据结构·算法·leetcode·面试
xiaokcehui2 小时前
地球物理大地测量学计算系列之十七局部重力场SRBF逼近及其性能指标测评
人工智能·算法·机器学习
Navigator_Z3 小时前
LeetCode //C - 1221. Split a String in Balanced Strings
c语言·算法·leetcode
天疆说3 小时前
庞特里亚金极小值原理的详细推导
算法