There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
這個問題等價于在一個有向圖中尋找有沒有圈。
我們找到?jīng)]有入度的節(jié)點,刪掉它,在其鄰接點的入度中將其去掉,再找下一個沒有入度的點。
樣下來如果沒有圈所有的點都會被去掉。如果有圈就剩下了這個圈,他們的入度永遠不可能互相去掉。
var canFinish = function(numCourses, prerequisites) {
var num = prerequisites.length;
if (num===0) return true;
var map = {};
var count = 0;
//遍歷數(shù)組,記錄下每個節(jié)點的入度和出度
for (let i = 0;i < num;i++) {
if (map[prerequisites[i][0]] === undefined) {
map[prerequisites[i][0]] = [new Set(),new Set()];
count++;
}
if (map[prerequisites[i][1]] === undefined) {
map[prerequisites[i][1]] = [new Set(),new Set()];
count++;
}
//入度
map[prerequisites[i][0]][0].add(prerequisites[i][1]);
//出度
map[prerequisites[i][1]][1].add(prerequisites[i][0]);
}
var lastRemove = [];
var removeing = [];
//找到所有沒有入度的點
for (let node in map) {
if (map[node][0].size===0)
lastRemove.push(parseInt(node));
}
while (count !== 0&&lastRemove.length !== 0) {
var numL = lastRemove.length;
count -= numL;
for (let i = 0; i < numL;i++) {
//要刪除的節(jié)點沒有入度,遍歷出度數(shù)組,找到鄰接點們
//從他們的入度中刪掉這個點,新的無入度的點將從這里產(chǎn)生
for (var j of map[lastRemove[i]][1]) {
map[j][0].delete(lastRemove[i]);
if (map[j][0].size === 0) removeing.push(j);
}
}
lastRemove = removeing;
removeing = [];
}
//如果沒有刪除所有的點,就說明有圈
if (count !== 0)
return false;
return true;
};