BFS vs. DFS
Prompt
We model our service dependencies as a graph and keep reaching for graph traversals — "what depends on this", "is there a dependency cycle", "fewest hops between two services". Walk me through how you'd pick BFS versus DFS for a problem like these, and what drives the choice.
How this round runs
This one's about reasoning, not reciting — I want you to commit to when each fits and defend it, and I'll hand you a concrete variant to see if your rule of thumb survives contact.
Model answer
Clarify first: directed or undirected? Weighted edges, or all hops equal? Could there be cycles, so I need visited-tracking to avoid looping? Roughly how wide versus deep is the graph — that drives the space trade-off.
Both are O(V + E) time. The real choice is shape and goal. BFS expands level by
level with a queue, so the first time it reaches a node is along the fewest edges
— that's why BFS gives shortest paths in an unweighted graph. DFS plunges down
one branch with a stack or recursion and backtracks, which is the natural fit for
"explore every path", topological ordering, and cycle detection. Space differs:
BFS holds a whole frontier, up to O(V) and painful on a wide graph; DFS holds a
single path, O(h) for depth h, but risks a deep recursion stack.
function bfs(start) {
const queue = [start];
const visited = new Set([start]);
while (queue.length > 0) {
const node = queue.shift();
for (const nb of node.neighbors) {
if (!visited.has(nb)) { visited.add(nb); queue.push(nb); }
}
}
}
function dfs(node, visited) {
visited.add(node);
for (const nb of node.neighbors) {
if (!visited.has(nb)) dfs(nb, visited);
}
}
So for "fewest hops between two services" I'd reach for BFS; for "is there a dependency cycle" I'd reach for DFS and track nodes on the current recursion path. Both need visited-tracking or they loop forever on a cyclic graph.
- Asked whether edges are weighted before claiming BFS gives shortest paths
- Tied BFS to shortest-path/levels and DFS to cycles/topological order with reasons
- Contrasted the space cost: O(V) frontier vs O(h) path
- Flagged that both need visited-tracking on a cyclic graph
- Fewest hops between two services → BFS, and stop as soon as the target is dequeued
- Detect a dependency cycle in a directed graph → DFS with an on-stack / in-progress marker, not just a visited set