Course Schedule课程表12(用Topological Sorting)
[抄题]:
现在你总共有 n 门课需要选,记为 0
到 n - 1
.
一些课程在修之前需要先修另外的一些课程,比如要学习课程 0 你需要先学习课程 1 ,表示为[0,1]
给定n门课以及他们的先决条件,判断是否可能完成所有课程?
给定 n = 2
,先决条件为 [[1,0]]
返回 true
给定 n = 2
,先决条件为 [[1,0],[0,1]]
返回 false
[思维问题]:
不知道为啥是图:抽象图,很多条边构造出来的图
[一句话思路]:
拓扑排序:先统计度、边数,再把度=0的点放进queue,进行BFS,减度
BFS时每层数一遍先修课程数相同的点,最后看总数是否相等
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 队列存的时候不指定类型,否则课程多了存不下。取出的时候转为整数
[二刷]:
- numCourses的个数>=int[][] prerequisites的组数,因此edge degree都要分配numCourses的空间
- 每一个edges[i]也是数组,因为里面存了很多条边。
- 队列里添加的是12345,统计个数,而不是统计degree[i](都是1)
- int pointer = (int)edges[course].get(i); 第course个边数组中的第i条边取出来,用pointer缩写,可以减度
[三刷]:
- 在所有的课中,如果入度 = 0,就压入queue之中。因此循环上限是numCourses
- List[] edges = new ArrayList[];List edges = new ArrayList; ArrayList实现的是List,ArrayList数组实现的是List数组,二者不同
[四刷]:
[五刷]:
[总结]:
- 图的BFS一定要用queue来实现。拓扑排序中,每次都添加度为0的下一层。搞明白原理
- 把变量名按自然语言写全了,这样更像是一个工业产品,而不是一些潦草的草稿
- degree表示入度,degree=0的点是先修课程 没有入度
[debug]:数组角标写错了,没查出来
[复杂度]:Time complexity: O(边+点) Space complexity: O(边+点)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
Topological Sorting:由偏序得到全序。统计入度、把入度=0的点放进队列、BFS
[其他解法]:
[Follow Up]:
返回序列
[LC给出的题目变变变]:
courese 3:范围排序,用PQ
310. Minimum Height Trees:长得宽的树,用宽搜
public class Solution { /* * @param numCourses: a total of n courses * @param prerequisites: a list of prerequisite pairs * @return: true if can finish all courses or false */ public boolean canFinish(int numCourses, int[][] prerequisites) { //corner case if (numCourses == 0 && prerequisites == null) { return false; } //count degree & edges int[] degree = new int[numCourses]; List[] edges = new ArrayList[numCourses];// for (int i = 0; i < numCourses; i++) { edges[i] = new ArrayList<Integer>(); } for (int i = 0; i < prerequisites.length; i++) { degree[prerequisites[i][0]] ++ ; edges[prerequisites[i][1]].add(prerequisites[i][0]); } //put in queue Queue queue = new LinkedList(); for (int i = 0; i < prerequisites.length; i++) { if (degree[i] == 0) { queue.add(i); } } //bfs int count = 0; while (!queue.isEmpty()) { int course = (int)queue.poll(); count ++; int n = edges[course].size(); for (int i = 0; i < n; i++) { int pointer = (int)edges[course].get(i); degree[pointer] --; if (degree[pointer] == 0) { queue.add(pointer); } } } return count == numCourses; } }