function hasCycle(graph: Map<number, number[]>): boolean {
const visited = new Set<number>();
const recStack = new Set<number>();
function dfs(node: number): boolean {
if (!visited.has(node)) {
visited.add(node);
recStack.add(node);
for (const neighbor of graph.get(node) || []) {
if (!visited.has(neighbor) && dfs(neighbor)) {
return true;
} else if (recStack.has(neighbor)) {
return true;
}
}
}
recStack.delete(node);
return false;
}
for (const node of graph.keys()) {
if (dfs(node)) {
return true;
}
}
return false;
}
const graph = new Map<number, number[]>([
[1, [2]],
[2, [3]],
[3, [4]],
[4, [2]]
]);
console.log(hasCycle(graph));The graph has edges 1→2, 2→3, 3→4, and 4→2. The edge 4→2 creates a cycle involving nodes 2, 3, and 4. The DFS detects this cycle and returns true.
function detectCycle(graph: Map<number, number[]>): boolean {
const visited = new Set<number>();
const recStack = new Set<number>();
function dfs(node: number): boolean {
if (!visited.has(node)) {
visited.add(node);
recStack.add(node);
for (const neighbor of graph.get(node) || []) {
if (!visited.has(neighbor) && dfs(neighbor)) {
return true;
} else if (recStack.has(neighbor)) {
return true;
}
}
}
recStack.delete(node);
return false;
}
for (const node of graph.keys()) {
if (dfs(node)) {
return true;
}
}
return false;
}
const graph = new Map<number, number[]>([
[1, [2]],
[2, [3]],
[3, [4]],
[4, []]
]);
console.log(detectCycle(graph));The graph edges are 1→2, 2→3, 3→4, and 4 has no outgoing edges. There is no cycle, so the function returns false.
The recursion stack keeps track of nodes currently being explored in the current DFS path. If a node is revisited while still in this stack, it means a cycle exists (a back edge).
function checkCycle(graph: Map<number, number[]>): boolean {
const visited = new Set<number>();
const recStack = new Set<number>();
function dfs(node: number): boolean {
if (visited.has(node)) {
return false;
}
visited.add(node);
recStack.add(node);
for (const neighbor of graph.get(node) || []) {
if (!visited.has(neighbor) && dfs(neighbor)) {
return true;
} else if (recStack.has(neighbor)) {
return true;
}
}
recStack.delete(node);
return false;
}
for (const node of graph.keys()) {
if (dfs(node)) {
return true;
}
}
return false;
}
const graph = new Map<number, number[]>([
[1, [2]],
[2, [3]],
[3, [1]]
]);
console.log(checkCycle(graph));The code incorrectly returns false immediately if a node is visited, without checking if it is in the recursion stack. This causes it to miss cycles and return false even when a cycle exists.
const graph = new Map<number, number[]>([ [1, [2, 3]], [2, [4]], [3, [2]], [4, [1, 5]], [5, []] ]);
The graph contains two cycles: 1→2→4→1 and 1→3→2→4→1. Both are distinct cycles involving different paths.
