leetcode 207. 课程表
问题描述: 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
- 例如,先修课程对
[0, 1]表示:想要学习课程0,你需要先完成课程1。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
示例 1:
输入: numCourses = 2, prerequisites = [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
示例 2:
输入: numCourses = 2, prerequisites = [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
思路: 用图的结构来解释这个问题。 1.统计出每个课程的要修之前需要先修几门课,形成一个数组degree。 2.用哈希表来记录,每个课(键)之前需要修的课程数组(值)。 3.建立队列,将degree中是0的课程放到队列中(这些课程不依赖别的课,可以直接修) 4.对队列开始执行while,只要队列中有值,就把队顶值取出来,然后对该对顶对应的map值进行遍历,对该建会影响的后续课程都减一,遇到degree是0的就加入队列,以此类推。
/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}
*/
var canFinish = function(numCourses, prerequisites) {
let degree=new Array(numCourses).fill(0);
let map=new Map();
for(let i=0;i<prerequisites.length;i++){
degree[prerequisites[i][0]]++;
map.has(prerequisites[i][1])?map.get(prerequisites[i][1]).push(prerequisites[i][0]):map.set(prerequisites[i][1],[prerequisites[i][0]])
}
let count=0;
let q=new Array()
for(let i=0;i<degree.length; i++){
if(degree[i]==0)q.push(i)
}
while(q.length){
let top=q.shift();
count++;
let key=map.get(top);
if(key&&key.length){
for(let i=0;i<key.length;i++){
degree[key[i]]--;
if(degree[key[i]]==0){
q.push(key[i])
}
}
}
}
return count==numCourses
};