Fundamentals/Patterns/Topological Sort (Kahn's BFS)7 problems· Graph

Process nodes in dependency order using indegree + queue

When to useCourse schedule, build order, alien dictionary, dependency resolution

iterative
Topological Sort | Topological Order
topo_intro
Alien Dictionary
alien_dictionary
Course Schedule
course_schedule
Longest Path | Dynamic Programming
longest_path
Reconstructing Sequence
sequence_reconstruction
Task Scheduling
task_scheduling
Task Scheduling 2
task_scheduling_2
INITIALIZE
build adjacency list and indegree map
const adj = Array.from({ length: n }, () => []);
const indegree = new Array(n).fill(0);
for (const [from, to] of edges) {
adj[from].push(to);
indegree[to] += 1;
}
const order = [];
const graph = new Map();
const inDegree = new Map();
for (const word of words) {
for (const ch of word) {
if (!graph.has(ch)) { graph.set(ch, new Set()); inDegree.set(ch, 0); }
}
}
const adj = Array.from({ length: numCourses }, () => []);
const indegree = new Array(numCourses).fill(0);
for (const [a, b] of prerequisites) { adj[b].push(a); indegree[a]++; }
const indegree = new Array(n).fill(0);
for (let u = 0; u < n; u++) for (const v of adj[u]) indegree[v]++;
const dist = new Array(n).fill(0); let best = 0;
const graph = new Map(); const inDegree = new Map();
// init all nodes; for each seq, add directed edges between consecutive elements
const graph = new Map(); const inDegree = new Map();
for (const t of tasks) { graph.set(t, []); inDegree.set(t, 0); }
for (const [a, b] of requirements) { graph.get(a).push(b); inDegree.set(b, inDegree.get(b) + 1); }
const graph = new Map();
const inDegree = new Map();
const duration = new Map();
for (let i = 0; i < tasks.length; i++) {
graph.set(tasks[i], []);
inDegree.set(tasks[i], 0);
duration.set(tasks[i], times[i]);
}
for (const [a, b] of requirements) {
graph.get(a).push(b);
inDegree.set(b, inDegree.get(b) + 1);
}
let total = 0;
seed queue
enqueue all nodes with indegree 0
const queue = [];
for (let i = 0; i < n; i++) {
if (indegree[i] === 0) queue.push(i);
}
let head = 0;
const queue = [];
for (const [ch, deg] of inDegree) if (deg === 0) queue.push(ch);
queue.sort();
let result = '';
for (let i = 0; i < numCourses; i++) if (indegree[i] === 0) queue.push(i);
for (let i = 0; i < n; i++) if (indegree[i] === 0) queue.push(i);
for (const [node, deg] of inDegree) if (deg === 0) queue.push(node);
for (const t of tasks) if (inDegree.get(t) === 0) queue.push(t);
const finishTime = new Map();
const queue = [];
for (const t of tasks) {
if (inDegree.get(t) === 0) {
queue.push(t);
finishTime.set(t, duration.get(t));
}
}
TRAVERSE
while queue is non-empty
while (head < queue.length) {
while (queue.length > 0) {
while (queue.length > 0) {
while (queue.length > 0) {
while (queue.length > 0) {
while (queue.length > 0) {
while (queue.length > 0) {
dequeue
pop node; add to result
const node = queue[head++];
order.push(node);
const ch = queue.shift();
result += ch;
const course = queue.shift(); processed++;
const node = queue.shift();
const node = queue.shift(); result.push(node);
const t = queue.shift(); result.push(t);
const t = queue.shift();
total = Math.max(total, finishTime.get(t));
[DECREMENT]
decrement neighbors' indegree; enqueue if hits 0
for (const next of adj[node]) {
indegree[next] -= 1;
if (indegree[next] === 0) queue.push(next);
}
for (const next of [...graph.get(ch)].sort()) {
inDegree.set(next, inDegree.get(next) - 1);
if (inDegree.get(next) === 0) { queue.push(next); queue.sort(); }
}
for (const next of adj[course]) {
if (--indegree[next] === 0) queue.push(next);
}
for (const next of adj[node]) {
dist[next] = Math.max(dist[next], dist[node] + 1);
best = Math.max(best, dist[next]);
if (--indegree[next] === 0) queue.push(next);
}
if (queue.length > 1) return false; // uniqueness check
for (const next of graph.get(node)) {
inDegree.set(next, inDegree.get(next) - 1);
if (inDegree.get(next) === 0) queue.push(next);
}
for (const next of graph.get(t)) {
inDegree.set(next, inDegree.get(next) - 1);
if (inDegree.get(next) === 0) queue.push(next);
}
for (const next of graph.get(t)) {
const candidate = finishTime.get(t) + duration.get(next);
finishTime.set(next, Math.max(finishTime.get(next) ?? 0, candidate));
inDegree.set(next, inDegree.get(next) - 1);
if (inDegree.get(next) === 0) queue.push(next);
}
RETURN
result if length matches node count, else cycle exists
if (order.length !== n) return [];
return order;
return result.length === inDegree.size ? result : '';
return processed === numCourses;
return best;
return result.length === n && result.every((v, i) => v === original[i]);
return result;
return total;