[LeetCode] 207. 课程表(拓扑排序,BFS)
题目
现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?
示例 1:
输入: 2, [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
示例 2:
输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。
说明:
输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
你可以假定输入的先决条件中没有重复的边。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
- 拓扑排序。
- 数据结构:构建邻接表;入度数组;并使用队列维护待处理的入度为0的顶点;因为此处不需要拓扑序列,所以维护一个待放入拓扑序列顶点数即可,最后若待处理顶点数==0则说明可拓扑排序无环。
- 做BFS,当队列不空:删掉入度为0的点,删掉该点出去的所有边;更新pointCnt;更新入度数组,将新的入度为0的点入队。
- 此外,次题不考虑重边,输入的int[][] prerequisites 矩阵每一行存了一条弧的起点和终点。
相关
图的表示方法
1.邻接矩阵:矩阵m[i][j]表示i到j是否有弧/权重。有稀疏问题。
2.临接表:对图的每个节点,用一个单向链表列出从该节点出发的所有弧,链表中每个节点对应于一条出弧。
3.关联矩阵:矩阵每一行是一个点,每一列是描述一个弧(1表示弧的起点,-1表示弧的终点)。有稀疏问题。
4.弧表示法
5.星型表示法
很好的参考文章:https://blog.csdn.net/woaidapaopao/article/details/51732947
拓扑序列与拓扑排序
AOV网:通常,把顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。
在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。
拓扑排序的另一个重要作用是可以判断有向图是否无环
拓扑排序算法流程(同时可以用来判断有向图是否无环)
当还有入度为0的点未放入结果序列:
1 选择一个入度为0的顶点并放入结果序列尾
2 从网中删除此顶点及所有出边。
结束后,若结果集中未包含全部点(即产生入度不为0的点无法放入),则说明图中有环,否则结果序列就是一个拓扑序列。
代码
public boolean canFinish(int numCourses, int[][] prerequisites) {
int pointCnt = numCourses;// 未放入拓扑序列的点的个数
HashMap<Integer, List<Integer>> adjList = new HashMap<>();// 邻接表
int[] inDegree = new int[numCourses];// 存放顶点入度
LinkedList<Integer> pointQue = new LinkedList<>();// 存放当前待处理的入度为0的顶点
for (int[] edge : prerequisites) {
// 初始化邻接表
List<Integer> tempList = adjList.getOrDefault(edge[0], new LinkedList<>());
tempList.add(edge[1]);
adjList.put(edge[0], tempList);
// 初始化顶点入度数组
inDegree[edge[1]]++;
}
// 入度为0的点放入队列
for (int i = 0; i < numCourses; ++i) {
if (inDegree[i] == 0) {
pointQue.addLast(i);
}
}
// 删掉入度为0的点,删掉关联的所有边;更新pointCnt;更新入度数组,将新的入度为0的点入队。
while (!pointQue.isEmpty()) {
int u = pointQue.removeFirst();
pointCnt--;
if (adjList.containsKey(u)) {//
for (int v : adjList.get(u)) {
inDegree[v]--;
if (inDegree[v] == 0) {
pointQue.push(v);
}
}
}
}
return pointCnt == 0;
}
参考链接
https://blog.csdn.net/qq_41713256/article/details/80805338
[LeetCode] 207. 课程表(拓扑排序,BFS)的更多相关文章
- LeetCode编程训练 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- Java实现 LeetCode 207 课程表
207. 课程表 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] ...
- C#LeetCode刷题-拓扑排序
拓扑排序篇 # 题名 刷题 通过率 难度 207 课程表 40.0% 中等 210 课程表 II 39.8% 中等 329 矩阵中的最长递增路径 31.0% 困难
- Leetcode 207.课程表
课程表 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总 ...
- [LeetCode] 207 Course Schedule_Medium tag: BFS, DFS
There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...
- leetcode 207课程表
class Solution { public: bool canFinish(int numCourses, vector<vector<int>>& prerequ ...
- LeetCode 207. Course Schedule(拓扑排序)
题目 There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have p ...
- LeetCode:课程表【207】
LeetCode:课程表[207] 题目描述 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹 ...
- 拓扑排序(附LeetCode题目)
算法期中考到一题关于拓扑序的题目,觉得很值得一写. 1.什么是拓扑序? 对一个有向无环图进行拓扑排序,假如图中存在一条从顶点A到顶点B的路径,则拓扑序中顶点A出现在顶点B的前面.要注意的是,这是对有向 ...
随机推荐
- Golang gRPC学习(04): Deadlines超时限制
为什么要使用Deadlines 当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行.Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 ...
- 【算法•日更•第五十七期】快速傅里叶变换(FFT):从入门到放弃
▎一些用的上的东西 小编太菜了,很多东西都不会证明(主要是三角函数还没有学啊~~~). 附上链接https://blog.csdn.net/enjoy_pascal/article/details/8 ...
- Spring Boot系列(二):Spring Boot自动装配原理解析
一.Spring Boot整合第三方组件(Redis为例) 1.加依赖 <!--redis--> <dependency> <groupId>org.springf ...
- Dubbo系列之 (五)服务订阅(2)
辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...
- Spring Security拦截器加载流程分析--练气中期
写在前面 上回我们讲了spring security整合spring springmvc的流程,并且知道了spring security是通过过滤器链来进行认证授权操作的.今天我们来分析一下sprin ...
- 安国AU6989主控 + K9GBG08U0A(NAND) 制作4GB闪存驱动器
文档标识符:AU6989_FLASH-DRIVE_D-P8 作者:DLHC 最后修改日期:2020.8.22 本文链接: https://www.cnblogs.com/DLHC-TECH/p/AU6 ...
- Hello,Vue
Vue版本 Vue完整版 有编译器compiler,体积大功能多,可以直接把html字符串变成DOM节点 视图,此处为html字符串,写在index.html里或者写在new Vue构造选项templ ...
- 牛客网PAT练兵场-组个最小数
题解:从小到大输出 题目地址:https://www.nowcoder.com/questionTerminal/86ede762b450404dbab59352963378e9 /** * *作者: ...
- Java I/O体系从原理到应用(非原创)
基础概念 在介绍I/O原理之前,先重温几个基础概念: 1 操作系统与内核 操作系统:管理计算机硬件与软件资源的系统软件内核:操作系统的核心软件,负责管理系统的进程.内存.设备驱动程序.文件和网络系统等 ...
- SecureCRT 关键字高亮显示
grep命令红色高亮关键字 1. 左边侧栏 Session Manage 右键Sessions --Properties 2 Terminal--Appearance Current color s ...
