function canFinish(numCourses, prerequisites) { const adj = Array.from({length: numCourses}, () => []);◄const indeg = new Array(numCourses).fill(0);
for (const [a, b] of prerequisites) {adj[b].push(a); // b is a prerequisite of a
indeg[a]++;
}
const queue = [];
for (let c = 0; c < numCourses; c++)
if (indeg[c] === 0) queue.push(c);
let taken = 0;
while (queue.length) {const u = queue.shift();
taken++;
for (const v of adj[u]) {indeg[v]--;
if (indeg[v] === 0) queue.push(v);
}
}
return taken === numCourses;
}
Treat each course as a node and each prerequisite [a, b] as an arrow b → a (“take b before a”). You can finish everything exactly when these arrows contain no cycle.
For each course, count how many prerequisites it still needs — its indegree. A course with indegree 0 has nothing blocking it, so it can be taken right now.
Take any ready course and “complete” it: that removes one prerequisite from every course that depended on it. Some of those may drop to indegree 0 and become ready themselves.
Keep taking ready courses. If you take all of them, there was no cycle → true. If you get stuck with courses whose indegree never reaches 0, they depend on each other in a cycle → false.