51.课程表(拓扑排序)-leetcode207

1.题目描述

你这个学期必须选修 numCourses 门课程,记为 0numCourses - 1

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai必须 先学习课程 bi

  • 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false

示例 1:

复制代码
输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

示例 2:

复制代码
输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

2.思路

建立邻接表,用二维数组edge表示,edgeij:编号为i的课程,其后续课程的编号为edgei这一行的所有元素,建立一个入度数组,如果一共有5门课程,这个数组的最后一个元素就是In4,每当有一个边如{1,2},表示课程1的先修课程为2,由2->1,可以让in1++,edge1这一行中加入2这个元素,edge1 = {2},直接可以用edge1.push_back(2);

搞懂了这些就可以描述算法了,初始状态为遍历in数组,找出入度为0的课程编号入队列,每次取一个编号出来,然后把这个编号的后修课程(遍历edge数组可以得到)对应的in数组减完1后为0的话就入队列,如1的入度为0,入队列,然后找出1的后修课程架设为2,3,In2--,in3--,如果in2=0了,则继续2入队列,重复直到队列为空,每次弹出一个元素表示这个编号的课程处理完毕了,count++,最后对比count和课程数的关系,如果相等就表示全部学完了,返回true,否则没有学完,返回false

3.代码

cpp 复制代码
class Solution {
public:
    vector<vector<int>> edges;//边数组,如edges[1]这个数组,存的是以课程1为先修课程的课程,也就是学完课程1就可以完成的课程
    vector<int> in;//入度数组,记录所有课程的入度,如in[0]=2,表示课程0的先修课程还有2个,现在不能完成课程0
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        edges.resize(numCourses);
        in.resize(numCourses, 0); // 初始入度全部为0,更严谨
        for(int i = 0;i<prerequisites.size();i++){
            //prerequisites是一个numCourses*2的数组,只有两列
            int precourse = prerequisites[i][1];//表示某个先修课程编号
            int backcourse = prerequisites[i][0];//后修课程的编号
            edges[precourse].push_back(backcourse);
            in[backcourse]++;//入度加一
        }
        queue<int> q;//存储课程编号的队列,只有入度为0的节点可以入队
        for(int i=0; i<numCourses;i++){
            if(in[i]==0){
                q.push(i);
            }
        }
        int count = 0;
        while(!q.empty()){
            count++;//记录学习多少门课程了
            int u = q.front();
            q.pop();
            for(int i =0;i<edges[u].size();i++){
                in[edges[u][i]]--;//u的邻接课程的入度减1
                if(in[edges[u][i]]==0){
                    q.push(edges[u][i]);
                }
            }
        }
        return count==numCourses;
    }
};
相关推荐
阳明山水33 分钟前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构
桐盛科技1 小时前
拒绝“漂绿”风险:基于边缘计算的碳排放数据清洗算法与实时校验逻辑
人工智能·算法·边缘计算
wuyk5551 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
-dzk-1 小时前
【链表】LC 138.随机链表的复制
数据结构·链表
Tongzhi20261 小时前
通芝科技考勤软件三大发展趋势:AI大模型、无感识别与数据底座
大数据·科技·算法·爬山算法
eBest数字化转型方案2 小时前
Route Optimization for FMCG:多目标排线算法的工程实现
大数据·人工智能·算法
洋不写bug2 小时前
链表补充练习,双链表的模拟实现
java·数据结构·链表·双链表·底层实现
residual_fan2 小时前
持续对比强化学习(Continual Contrastive Reinforcement Learning)论文分享
人工智能·算法·数据挖掘·数据分析
s_w.h3 小时前
【 计网 】序列化与反序列化
linux·服务器·网络·算法·bash
信奥卷王3 小时前
2025年09月GESPC++五级真题解析(含视频)
算法