思路:
创建入度数组填充为0,存放对应索引值位置的入度
创建邻接表存储对应的键值,需要先修的课程为建,依赖于它的课程为值
将所有入度为0的元素入列,即为没有依赖先修课程的课程
将队列中不依赖先修的课程出列,匹配map中所对应的依赖于这些课程的后续课程,对他们的入度--
如果入度为0了,则将其加入到队列中
最后返回课程数与出队的课程数是否相等,相等则说明可以修完
/*
* 1.记录腐烂橘子坐标和新鲜橘子数量
* 2.出队腐烂橘子,对四周进行infect,同时减少新鲜橘子数量
* */
var canFinish = function (numCourses, prerequisites) {
const inDegree = new Array(numCourses).fill(0); //存放每门课的数组,入度为0即代表没有先修课程,为k即代表k门先修课程
const map = {};//存放入度为0课程对应依赖其作为先修课程的课程
for (let i = 0; i < prerequisites.length; i++) {
inDegree[prerequisites[i][0]]++;//对应课程入度++
if(map[prerequisites[i][1]]){//先修课程为键,依赖其作为先修的课程为值
map[prerequisites[i][1]].push(prerequisites[i][0]);//push
}else{
map[prerequisites[i][1]] = [prerequisites[i][0]];//在数组中进行Push所以要为[]
}
}
const queue = [];//存放没有先修课程的课程,即入度为0的课程
for (let i = 0; i < inDegree.length; i++) {
if(inDegree[i] === 0) queue.push(i);
}
let count = 0;//已修课程数
while (queue.length){//入度为0课程不为空,因为只有先修相应课程后才能修依赖其先修的课程
const selected = queue.shift();//入度为0的课程出队,
count++;//已修课程数+1
const toEnqueue = map[selected];//map中所依赖其作为先修的课程
if(toEnqueue){//不为空
for (let i = 0; i < toEnqueue.length; i++) {
inDegree[toEnqueue[i]]--;//依赖于它的后续课的入度--
if(inDegree[toEnqueue[i]] === 0)//如果更新后入度为0,表示它没有先修课程了,添加到队列中
queue.push(toEnqueue[i]);//添加依赖其作为先修的课到队列
}
}
}
//如果已修课程与全部课程相等,说明可以修完,否则说明有课程无法修完
return count === numCourses;
}
重点在于搞清楚map,toEnqueue,inDegree,selected之间的关系
课程表(拓扑排序)
最新推荐文章于 2024-10-02 23:40:03 发布