Second question: How would you check if a graph is connected or not
Run a single BFS/DFS from any node and check whether every node was visited. O(V+E). For directed graphs, distinguish weak vs strong connectivity (strong needs Kosaraju/Tarjan or a check from one node on both the graph and its transpose).
"Is the graph connected?" = can you reach every node from some starting node. One traversal answers it.
Undirected graph — single traversal
function isConnected(graph) { // graph: adjacency list, n nodes
const nodes = Object.keys(graph);
if (nodes.length === 0) return true; // or define per spec
const visited = new Set();
const stack = [nodes[0]]; // start anywhere
while (stack.length) {
const node = stack.pop();
if (visited.has(node)) continue;
visited.add(node);
for (const next of graph[node]) {
if (!visited.has(next)) stack.push(next);
}
}
return visited.size === nodes.length; // reached everything?
}BFS works identically (queue instead of stack). Complexity: O(V + E) time, O(V) space.
Directed graphs — "connected" is ambiguous
- Weakly connected — connected if you ignore edge direction. Treat edges as undirected, run the above.
- Strongly connected — every node reaches every other node respecting direction. Options:
- Cheap check: DFS from any node on the graph; DFS from the same node on the transpose (all edges reversed). If both reach all nodes, it's strongly connected.
- General (find all components): Kosaraju's or Tarjan's SCC algorithm — still O(V + E).
Alternative for undirected: Union-Find
Union every edge, then check all nodes share one root. O(E·α(V)) ≈ O(E). Especially nice if edges arrive incrementally or you also need to answer "are these two connected?" repeatedly.
Edge cases to mention
- Empty graph — define with the interviewer (vacuously true, or invalid).
- Single node, no edges — connected.
- Isolated/unreachable nodes — exactly what makes it disconnected.
- Self-loops and parallel edges —
visitedset handles them; don't infinite-loop. - Disconnected input —
visited.size < n.
What interviewers want
State the O(V+E) bound, ask "directed or undirected?" before coding, and know that directed connectivity splits into weak vs strong with different algorithms. Mentioning Union-Find as an alternative is a plus.
Follow-up questions
- •How does the answer change for a directed graph?
- •What's the difference between weak and strong connectivity?
- •When would Union-Find be a better choice than BFS/DFS?
- •How do you find the number of connected components?
Common mistakes
- •Not asking whether the graph is directed or undirected.
- •Forgetting the visited set and infinite-looping on cycles.
- •Checking only that the traversal ran, not that it reached every node.
- •Assuming strong connectivity is the same as weak for directed graphs.
Performance considerations
- •BFS/DFS is O(V+E) time, O(V) space — optimal for a one-off check. Union-Find is near-linear and better when edges stream in or you need repeated connectivity queries. SCC algorithms (Kosaraju/Tarjan) stay O(V+E) for the directed case.
Edge cases
- •Empty graph — clarify the definition.
- •Single isolated node.
- •Self-loops and parallel edges.
- •Already-disconnected graph with multiple components.
Real-world examples
- •Detecting network partitions / isolated nodes in a topology.
- •Validating that a dependency graph or social graph has no orphaned clusters.