207 课程表
你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]
给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
第一次做图的拓扑排序相关。
顺便记录一下拓扑排序。
function canFinish($numCourses, $prerequisites) {
$edges = array_fill(0, $numCourses, []);
$indegree = [];
//统计出各个节点的邻接点放到edgs,相关节点的入度情况。
//选好前导节点和当前节点
foreach ($prerequisites as $prerequisite) {
$cur = $prerequisite[0];
$pre = $prerequisite[1];
$edges[$pre][] = $cur;
$indegree[$cur]++;
}
//找到所有入度为0的节点,准备模拟去边操作
$queue = new SplQueue();
for ($i = 0; $i < $numCourses; $i++) {
if ($indegree[$i] == 0) {
$queue->enqueue($i);
}
}
$res = 0;
while (!$queue->isEmpty()) {
$res++;
//开始模拟去边操作。去掉当前节点
$u = $queue->dequeue();
foreach ($edges[$u] as $v) {
//当前节点的入度减一,
$indegree[$v]--;
//减到0就可以入队,之后就可以从该节点继续去边了。
if ($indegree[$v] == 0) {
$queue->enqueue($v);
}
}
}
//这道题判断的是是否能够学完所有课程,也就是能不能正好把所有的点都遍历到。
return $res == $numCourses;
}
课程表2
这个是给出一个可以学完所有课程的顺序。
function findOrder($numCourses, $prerequisites) {
//边
$edge = array_fill(0, $numCourses, []);
//入度
$in_degree = array_fill(0, $numCourses, 0);
//同样还是先搞出所有边,节点的入度情况。
foreach ($prerequisites as $prerequisite) {
//先导课程
$pre = $prerequisite[1];
$cur = $prerequisite[0];
$edge[$pre][] = $cur;//[2,1],1-->2
$in_degree[$cur]++;
}
$queue = new SplQueue();
//从一个入度为0的节点开始学习
for ($i = 0; $i < $numCourses; $i++) {
//找到所有度为0的
if ($in_degree[$i] == 0) {
$queue->enqueue($i);
}
}
$res = [];
while (!$queue->isEmpty()) {
$top = $queue->dequeue();
$res[] = $top;
$edges = $edge[$top];
foreach ($edges as $e) {
$in_degree[$e]--;
if ($in_degree[$e] == 0) {
$queue->enqueue($e);
}
}
}
return count($res) == $numCourses ? $res : [];
}