剑指 Offer II 113. 课程顺序


comments: true
edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20113.%20%E8%AF%BE%E7%A8%8B%E9%A1%BA%E5%BA%8F/README.md

剑指 Offer II 113. 课程顺序

题目描述

现在总共有 numCourses 门课需要选,记为 0 到 numCourses-1

给定一个数组 prerequisites ,它的每一个元素 prerequisites[i] 表示两门课程之间的先修顺序。 例如 prerequisites[i] = [ai, bi] 表示想要学习课程 ai ,需要先完成课程 bi 。

请根据给出的总课程数  numCourses 和表示先修顺序的 prerequisites 得出一个可行的修课序列。

可能会有多个正确的顺序,只要任意返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

 

示例 1:

输入: numCourses = 2, prerequisites = [[1,0]] 
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

示例 3:

输入: numCourses = 1, prerequisites = [] 
输出: [0]
解释: 总共 1 门课,直接修第一门课就可。

 

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • ai != bi
  • prerequisites 中不存在重复元素

 

注意:本题与主站 210 题相同:https://leetcode.cn/problems/course-schedule-ii/

解法

方法一:拓扑排序

拓扑排序的思路是,先统计每个节点的入度,然后从入度为 0 的节点开始,依次删除这些节点,同时更新与这些节点相连的节点的入度,直到所有节点都被删除。

这里使用队列来存储入度为 0 的节点,每次从队列中取出一个节点,将其加入结果数组中,然后遍历与这个节点相连的节点,将这些节点的入度减 1,如果减 1 后入度为 0,则将这些节点加入队列中。

最后判断结果数组的长度是否等于节点的个数,如果等于则返回结果数组,否则返回空数组。

时间复杂度 O ( n + m ) O(n + m) O(n+m),空间复杂度 O ( n + m ) O(n + m) O(n+m)。其中 n n n m m m 分别是节点的个数和边的个数。

Python3
class Solution:def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:graph=defaultdict(list)indg={} #其实目的还是为bfs第一层服务的for i in range(numCourses): #【注意】初始化,要不然第一层为空indg[i]=0 for b,a in prerequisites:graph[a].append(b)indg[b]+=1# 第一层q=deque()for node,ind in indg.items():if ind==0:q.append(node)print(q,indg)#bfsres=[]while q:for _ in range(len(q)):cur=q.popleft()res.append(cur)for nx in graph[cur]:indg[nx]-=1if indg[nx]==0:q.append(nx)return res if len(res)==numCourses else []
Java
class Solution {public int[] findOrder(int numCourses, int[][] prerequisites) {List<Integer>[] g = new List[numCourses];Arrays.setAll(g, k -> new ArrayList<>());int[] indeg = new int[numCourses];for (var p : prerequisites) {int a = p[0], b = p[1];g[b].add(a);++indeg[a];}Deque<Integer> q = new ArrayDeque<>();for (int i = 0; i < numCourses; ++i) {if (indeg[i] == 0) {q.offer(i);}}int[] ans = new int[numCourses];int cnt = 0;while (!q.isEmpty()) {int i = q.poll();ans[cnt++] = i;for (int j : g[i]) {if (--indeg[j] == 0) {q.offer(j);}}}return cnt == numCourses ? ans : new int[0];}
}
C++
class Solution {
public:vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {vector<int> g[numCourses];vector<int> indeg(numCourses);for (auto& p : prerequisites) {int a = p[0], b = p[1];g[b].push_back(a);++indeg[a];}queue<int> q;for (int i = 0; i < numCourses; ++i) {if (indeg[i] == 0) {q.push(i);}}vector<int> ans;while (q.size()) {int i = q.front();q.pop();ans.push_back(i);for (int j : g[i]) {if (--indeg[j] == 0) {q.push(j);}}}return ans.size() == numCourses ? ans : vector<int>();}
};
Go
func findOrder(numCourses int, prerequisites [][]int) []int {g := make([][]int, numCourses)indeg := make([]int, numCourses)for _, p := range prerequisites {a, b := p[0], p[1]g[b] = append(g[b], a)indeg[a]++}q := []int{}for i, v := range indeg {if v == 0 {q = append(q, i)}}ans := []int{}for len(q) > 0 {i := q[0]q = q[1:]ans = append(ans, i)for _, j := range g[i] {indeg[j]--if indeg[j] == 0 {q = append(q, j)}}}if len(ans) == numCourses {return ans}return []int{}
}
TypeScript
function findOrder(numCourses: number, prerequisites: number[][]): number[] {const g: number[][] = Array.from({ length: numCourses }, () => []);const indeg: number[] = Array(numCourses).fill(0);for (const [a, b] of prerequisites) {g[b].push(a);++indeg[a];}const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1);const ans: number[] = [];while (q.length) {const i = q.pop()!;ans.push(i);for (const j of g[i]) {if (--indeg[j] === 0) {q.push(j);}}}return ans.length === numCourses ? ans : [];
}
C#
public class Solution {public int[] FindOrder(int numCourses, int[][] prerequisites) {List<int>[] g = new List<int>[numCourses];for (int i = 0; i < numCourses; i++) {g[i] = new List<int>();}int[] indeg = new int[numCourses];foreach (var p in prerequisites) {int a = p[0], b = p[1];g[b].Add(a);++indeg[a];}Queue<int> q = new Queue<int>();for (int i = 0; i < numCourses; ++i) {if (indeg[i] == 0) {q.Enqueue(i);}}int[] ans = new int[numCourses];int cnt = 0;while (q.Count > 0) {int i = q.Dequeue();ans[cnt++] = i;foreach (int j in g[i]) {if (--indeg[j] == 0) {q.Enqueue(j);}}}return cnt == numCourses ? ans : new int[0];}
}
Swift
class Solution {func findOrder(_ numCourses: Int, _ prerequisites: [[Int]]) -> [Int] {var graph = Array(repeating: [Int](), count: numCourses)var indegree = Array(repeating: 0, count: numCourses)for prereq in prerequisites {let course = prereq[0]let prereqCourse = prereq[1]graph[prereqCourse].append(course)indegree[course] += 1}var queue = [Int]()for i in 0..<numCourses {if indegree[i] == 0 {queue.append(i)}}var order = [Int]()while !queue.isEmpty {let course = queue.removeFirst()order.append(course)for nextCourse in graph[course] {indegree[nextCourse] -= 1if indegree[nextCourse] == 0 {queue.append(nextCourse)}}}return order.count == numCourses ? order : []}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39233.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCould微服务架构之Docker(1)

项目中微服务比较多的时候&#xff0c;一个一个手动的部署太麻烦了&#xff0c;所以就需要用到Docker。 项目部署中的问题&#xff1a; Docker是一种快速交付应用、运行应用的技术。

软件公司高新技术企业代办:机遇与陷阱并存-优雅草卓伊凡

软件公司高新技术企业代办&#xff1a;机遇与陷阱并存-优雅草卓伊凡 在科技飞速发展的当下&#xff0c;软件公司如雨后春笋般涌现&#xff0c;众多企业渴望通过申请高新技术企业来获得政策支持与发展助力。随之而来的&#xff0c;是高新技术企业代办业务的兴起。然而&#xff…

动捕技术革新虚拟直播:解码虚拟主播的“拟真感“破局之路

在元宇宙技术加速落地的今天&#xff0c;虚拟直播已从早期的卡通形象展示&#xff0c;进化为具备情感交互的沉浸式体验&#xff0c;用户对"高拟真度互动"的需求也逐渐增加&#xff0c;这场行业变革的核心驱动力&#xff0c;离不开动捕技术的持续迭代。 虚拟直播的&q…

python字节码文件.pyc反编译成.py文件

一、前言 在 Python 开发过程中&#xff0c;.pyc 文件&#xff08;Python 字节码文件&#xff09;是 Python 解释器运行程序时生成的一种中间文件。它通常用于提高程序的运行效率&#xff0c;避免每次运行时都重新编译源代码。然而&#xff0c;由于各种原因&#xff0c;我们可…

C++友元:跨墙访问的三种姿势

目录 友元 友元之普通函数形式 友元之成员函数形式 友元类 友元的特点 友元 什么叫友元&#xff1f; 一般来说&#xff0c;类的私有成员只能在类的内部访问&#xff0c;类之外是不能访问它们的。但如果将其他类/函数设置为类的友元&#xff0c;那么友元类/函数就可以在前…

Typora安装使用教程 简单易用的Markdown编辑器

Typora markdown 编辑器下&#xff0c;最后一个免费版本 0.11.18&#xff0c;但可能会提示过期无法使用, 建议大家可以使用 0.9.96 Windows 版&#xff0c;下载 Windows X64 版。 Typora简介 Typora 是一款由 Abner Lee 开发的轻量级 Markdown 编辑器&#xff0c;与其他 Mark…

图解AUTOSAR_SWS_WatchdogInterface

AUTOSAR Watchdog Interface (WdgIf) 详解 AUTOSAR经典平台看门狗接口模块技术详解 目录 1. 概述 1.1 WdgIf模块的作用1.2 WdgIf在AUTOSAR中的位置2. 架构设计 2.1 WdgIf架构概览2.2 接口设计2.3 序列设计3. 配置详解 3.1 配置参数3.2 配置结构3.3 配置类型4. 总结 4.1 主要特点…

(Arxiv-2025)Magic 1-For-1:在一分钟内生成一分钟视频剪辑

Magic 1-For-1&#xff1a;在一分钟内生成一分钟视频剪辑 paper是PKU发布在Arxiv 2025的工作 paper title:Magic 1-For-1: Generating One Minute Video Clips within One Minute Code&#xff1a;地址 Abstract 在本技术报告中&#xff0c;我们提出了 Magic 1-For-1&#xff…

谷歌大型推理模型曝光!击败Claude-3.7-Thinking

哎&#xff01;最近推特上的网友在LMSYS Arena 发现了个泄漏的大模型 Nebula&#xff0c;效果据说特别好&#xff0c;打败了o1、o3-mini、Claude 3.7 Thinking等模型&#xff1a; 网友们通过询问和分析 API&#xff0c;发现这似乎是谷歌正在秘密测试的新推理模型&#xff01;推…

css-grid布局

文章目录 1、布局2、网格轨道3、间距Gap4、网格线5、网格别名 当一个 HTML 元素将 display 属性设置为 grid 或 inline-grid 后&#xff0c;它就变成了一个网格容器&#xff0c;这个元素的所有直系子元素将成为网格元素。 1、布局 启用grid布局类似与flex布局&#xff0c;不过g…

菱形虚拟继承的原理

一 &#xff1a;菱形继承的问题 普通的菱形继承存在数据冗余和二义性的问题 &#xff0c;如下代码&#xff1a; class Person { public:string _name; //姓名 };class Student : public Person { protected:int _num; //学号 };class Teacher : public Person { protected:int…

<数据集>轨道异物识别数据集<目标检测>

数据集下载链接&#xff1a;https://download.csdn.net/download/qq_53332949/90527370 数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1659张 标注数量(xml文件个数)&#xff1a;1659 标注数量(txt文件个数)&#xff1a;1659 标注类别数&#xff1a;6 标注类别…

高效PDF翻译解决方案:多引擎支持+格式零丢失

软件介绍 在AI翻译工具大行其道的今天&#xff0c;传统翻译软件市场逐渐饱和&#xff0c;但专业领域的深度需求依然存在。本文推荐的PDF翻译工具凭借20余种专业翻译接口&#xff0c;为学术文献、技术文档等复杂内容提供更精准的翻译服务&#xff0c;在保留文档原始排版的同时…

AI智能新标尺:诺姆·布朗谈token成本革命

第一章&#xff1a;从德州扑克到AI革命——诺姆布朗的“顿悟时刻” 1.1 从“人机对战”到“思维革命” 诺姆布朗的AI研究生涯始于2012年卡内基梅隆大学的实验室。彼时&#xff0c;国际象棋AI“深蓝”已横扫棋坛&#xff0c;围棋AI“AlphaGo”初露锋芒&#xff0c;但非完美信息…

碰一碰发视频系统开发者源码分析(一)

#碰一碰发视频系统# #碰一碰发视频saas系统#搭建 碰一碰发视频&#xff0c;是采用前沿技术搭载一套 AI 智能剪辑系统“碰一碰发视频”是一种基于近场通信&#xff08;NFC&#xff09;或蓝牙技术的创新交互方式&#xff0c;用户通过设备轻触即可触发视频传输或播放。本文将详细…

ROS2下MoveIt+Rviz+MuJoCo 三剑合璧!Panda 机械臂联动仿真!

视频讲解&#xff1a; ROS2下MoveItRvizMuJoCo 三剑合璧&#xff01;Panda 机械臂联动仿真&#xff01; 仓库代码&#xff1a;GitHub - LitchiCheng/ros2_package 今天介绍下&#xff0c;ros2下使用moveit在Rviz和mujoco联合仿真&#xff0c;结合上一期视频《MuJoCo 仿真 Pand…

Virtual BOX安装ubuntu及其环境配置(个人一些踩坑补充)

目录 设置中文操作界面和环境时候&#xff0c;下图内容切忌不要选错&#xff01;安装过程中因为分辨率原因&#xff0c;可能安装界面无法显示全面&#xff0c;如何临时解决这篇文章中的缺少如何调出中文输出法部分unbuntu换源安装terminal终端小鱼一键ros安装opencv环境配置 ub…

基于Spring Boot的三国之家网站的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

二分图相关

判断二分图&#xff08;染色&#xff09; #include<bits/stdc.h> using namespace std; void __p(int x) {cerr<<x;} void __p(long long x){cerr<<x;} void __p(long double x){cerr<<x;} void __p(double x){cerr<<x;} void __p(string s){cer…

java执行jar包提示没有主清单属性

以前都没遇到过这种情况&#xff0c;什么时候打jar&#xff0c; war包都没有遇到过&#xff0c; 按照网上说的创建了META-INF/MANIFEST.MF 还是报错 于是检查下maven 打包发现&#xff1a;竟然有skip 为true 去掉 skip true &#xff0c;进行打包&#xff0c;编译后正常