图论
方法1:BFS+入度
这题完全就是207题的姐妹题,207要求是否能学完课程,返回布尔,这里是返回一个学完课程的路径
下面是207的代码
public boolean canFinish(int numCourses, int[][] prerequisites) {
//1.计算入度表,[u,v] v->u
//入度(indegree)就是有向图中指向这个点的边的数量,即有向图的某个顶点作为终点的次数和
int[] indegrees = new int[numCourses];
for (int[] p : prerequisites) {
indegrees[p[0]]++;
}
//2.将入度为0的点放入queue中,queue中装的是点的下标索引,即是入度表中的索引
//题意:你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。课程名称与索引是对应的
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < indegrees.length; i++) {
if (indegrees[i] == 0) queue.offer(i);
}
//3.轮转这个queue,这个queue中弹出的节点其实是v->u中的v
//弹出一个节点,将课程数-1,在prerequisites中找到这个节点的指向节点,即通过v->u
//如果u找到了,将其入度-1,如果入度为0了,将其加到queue中
while (!queue.isEmpty()) {
int pre = queue.poll();//这个是v->u的v
numCourses--;
for (int[] p : prerequisites) {
if (p[1] != pre) continue;
indegrees[p[0]]--;
if (indegrees[p[0]] == 0) queue.offer(p[0]);
}
}
//判断有没有剩余的课程数
return numCourses == 0;
}只需要添加记录路径的逻辑
需要一个array来记录路径的大小,大小等于numCourse,因为要是能学完的话,是需要numCourse=0的 index记录加入路径的游标 完整代码
概念
拓扑排序
拓扑排序的定义
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
有向无环图在Spark的设计中是很核心的基础概念
拓扑排序能做什么?
用来检测是否有环
大体分三步:
1.在有向图中找出(没有前驱)入度为零的点,并且输出。
2.从图中删除以它为弧尾的边(删除从它出发的边)
3.重复1、2两步直至所有顶点全部输出,或者图中不存在入度为零的顶点(剩下的就是环),说明有向图有环。
一些概念
邻接表
邻接表是一种顺序分配和链式分配相结合的存储结构。 (即利用数组和链表相结合)
用数组存储每条链头结点(头结点即每个顶点),链结点存储的是边的内容(存储该顶点的邻接表或出边)。
头结点结构定义,需存储顶点信息即其后继边,保存后继关系。
链表结点保存边内容,包含该边所连终点编号,以及链的后继关系(但要注意,并非是边与边的后继关系。实际上是头结点顶点与边终点的后继关系)
利用一维数组保存头结点,称为邻接表
AOV&AOE
AOV网,顶点表示活动,弧表示活动间的优先关系的有向图。 即如果a->b,那么a是b的先决条件。
AOE网,边表示活动,是一个带权的有向无环图, 其中顶点表示事件,弧表示活动,权表示活动持续时间。
求拓扑序列就是AOV,求关键路径就是AOE
入度
入度(indegree)就是有向图中指向这个点的边的数量,即有向图的某个顶点作为终点的次数和
出度
出度(outdegree)就是从这个点出去的边的数量,即有向图的某个顶点作为起点的次数和

方法1:BFS+邻接矩阵
从叶子节点开始bfs,逐步深入到中心节点,最后一层bfs留下的点,是到叶子节点距离最短的点,也就是最小高度树的根节点
另外一种写法:
不使用queue存储叶子节点,不存储出度,size为1的邻接矩阵为出度为1的点,即叶子节点
方法2:BFS+邻接表
方法1:排序+BFS
方法2:Dijkstra 算法
方法1:BFS
方法1:01广度优先搜索
另,不适用vis标记数组
方法2:Dijkstra
方法3:Dijkstra

附
- 图算法专栏
方法1:邻接表+DFS
方法2:DFS
方法1:模拟
因为代价值都是正整数,所以往回走或者重复走都会增加代价,最佳方式是直角线走
方法3:拓扑排序
方法1:01-BFS
另 ,数组写法,不转换坐标
方法2:01BFS
Last updated