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

课程表---bfs

题目:

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 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 。这是不可能的。

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • prerequisites[i] 中的所有课程对 互不相同

思路:

本题可以转化为:课程安排是否是有向无环图。因为课程间规定了前置条件,但不能构成任何环路,否则课程前置条件将不成立。

思路是通过拓扑排序,判断此课程安排图是否是有向无环图。拓扑排序原理:对有向无环图的顶点进行排序。使得对每一条有向边(u,v),均有u(在排序记录中)比v先出现。亦可理解为对某点v而言,只有当v的所有源点均出现了,v才能出现。

通过课程前置条件列表prerequisites 可以得到课程安排图的邻接表adjacency,以降低算法时间复杂度,以下两种方法都会用到邻接表。

入度表(广度优先遍历)

1.统计课程安排图中每个节点的入度,生成入度表indegrees。

2.借助一个队列queue,将所有入度为0的节点入队。

3.当queue非空时,依次将队首节点出队,在课程安排图中删除此节点pre:

并不是真正的从邻接表删除此节点pre,而是将此节点对应所有邻接节点cur的入度-1,即indegrees[cur] -=1;

当入度-1后邻接节点cur的入度为0,说明cur所有的前驱节点已经被“删除”,此时将cur入队。

4.在每次pre出队时,执行numCourses--;

若整个课程安排图是有向无环图(即可以安排),则所有节点一定都入队并出队过,即完成拓扑排序。换个角度说,若课程安排图中存在环,一定有节点的入度始终不为 0。
因此,拓扑排序出队次数等于课程个数,返回 numCourses == 0 判断课程是否可以成功安排。
复杂度分析:
时间复杂度 O(N+M): 遍历一个图需要访问所有节点和所有临边,N 和 M 分别为节点数量和临边数量;
空间复杂度 O(N+M): 为建立邻接表所需额外空间,adjacency 长度为 N ,并存储 M 条临边的数据。

class Solution{public boolean canFinish(int numCourses,int[][] prerequisites){int [] indegrees = new int[numCourses];List<List<Integer>> adjacency = new ArrayList<>();Queue<Integer> que = new LinkedList<>();for(int i = 0;i < numCourses;i ++){adjacency.add(new ArrayList<>());}for(int i = 0;i < prerequisites.length;i ++){int [] cp = prerequisites[i];indegrees[cp[0]]++;adjacency.get(cp[1]).add(cp[0]);}for(int i = 0;i < numCourses;i ++)if(indegrees[i]==0) que.add(i);while(!que.isEmpty()){int pre = que.poll();numCourses--;for(int i = 0;i < adjacency.get(pre).size();i++){int cur = adjacency.get(pre).get(i);indegrees[cur]--;if(indegrees[cur] == 0){que.add(cur);}}}return numCourses == 0;}
}

http://www.dtcms.com/a/570006.html

相关文章:

  • Redis的数据淘汰策略解读
  • Spring EL 表达式
  • 利用海伦公式计算经纬度坐标点到直线的距离
  • 前端面试题最大矩形面积问题
  • 网站建设顺德营销型网站制作msgg
  • 19、【Ubuntu】【远程开发】技术方案分析:远程桌面
  • 从零到一:我的开源AI商业化实战之路
  • 景县网站建设在线培训平台
  • 第21课:前端界面开发:用Gradio构建RAG应用UI
  • 网站原型图是什么做网站的数据从哪里来
  • 网站文件权限设置金融投资网站源码
  • 织梦手机网站怎么修改密码html网站设计模板下载
  • 哪种网站开发最简单家庭宽带做网站稳定吗
  • 浅谈Linux内核kswapd的内存域(zone)扫描机制
  • 什么是北斗短报文终端?与卫星电话有什么区别?
  • Maven基础(一)
  • MAC-SQL:黄金标准错误
  • 怎样创建基本的网站电子商务网站建设的试卷
  • 网站加盟代理wordpress 本地调试
  • 如何使用AI快速编程实现标注ROS2中sensor_msgs/msg/Image图像色彩webots2025a
  • 专业定制网站开发公司做纺织的用什么网站
  • 20251104让AIO-3576Q38开发板跑Rockchip的原厂Android14进行性能测试【使用天启的DTS】
  • 【案例】三维扫描实现
  • 无人设备遥控器之天线技术分析
  • 宁波市建设工程监理协会网站工程公司年会发言稿
  • 广州旅游团购网站建设中山seo
  • mlir 编译器学习笔记之四 -- 调度
  • 网站建设实施步骤网站源代码上传
  • 2025年 汽车零部件行业MES厂商分析
  • 学校网站制作公司公司企业邮箱怎么填写