Graphs Coding Interview: Translate the Story, Then Choose a Traversal
A practical guide to graphs coding interview questions: translate the story into nodes and edges, choose BFS or DFS for a reason, and state complexity in concrete terms.
A graphs coding interview question rarely fails you because the code is hard. It fails you because the problem arrives as a story about courses, friends, flights or dependencies, and the graph is hidden inside it. The fix is not another template. It is a habit of reasoning out loud from the shape of the problem: what the nodes are, what the edges are, whether direction or weight matters, and which traversal the question is actually asking for.
Why Graphs Coding Interview Questions Feel Harder Than They Are
An array question usually announces itself. A graph question often does not. You are told about a student who wants to take courses in some order, or a list of pairs of people who know each other, or a set of flights with prices. Nothing in the prompt says "graph".
The difficulty is translation, not implementation. Once you have named the nodes and the edges, the code is often short — a queue, a visited set, and a loop. The part that trips people up is the step before that, where a paragraph of prose has to become a concrete model.
Interviewers are listening for that translation step. When you say out loud, "so the courses are nodes, and a prerequisite is a directed edge from the prerequisite to the course", you have turned a vague prompt into something you can reason about — and you have given the interviewer a chance to correct you before you write a line of code. That is far cheaper than debugging the wrong model twenty minutes later.
This guide is about the reasoning you narrate, not a memorised list of templates, because a template only helps when you have already recognised the problem, and recognition is exactly what fails on an unfamiliar question.
Step One: Turn the Story Into Nodes and Edges
Ask three questions, in this order.
- What is an entity here? That is a node.
- What relationship connects two entities? That is an edge.
- Does the relationship point one way, or both ways? That decides direction. Does it carry a cost or a distance? That decides weight.
Work through a few examples with that script.
Course prerequisites. The entities are courses. The relationship is "must be taken before". It is not symmetric: if course A must come before course B, course B does not come before course A. So this is a directed graph, with an edge from the prerequisite to the course that depends on it.
Friendships or connections. The entities are people. The relationship is "knows" or "is connected to". If it holds one way, it holds the other way too. This is an undirected graph, and you should say so, because it changes how you build the adjacency list and how you mark visited nodes.
Flights with prices. The entities are cities. The relationship is "there is a flight from one city to another at a given cost". Direction matters — a route out is not necessarily a route back — and cost matters. This is a weighted directed graph.
Notice how much you have already decided before writing any code: how to store adjacency, whether to add both directions, whether a plain traversal is even the right tool. Say the model out loud before you start. "I am going to treat this as a directed graph where each node is a course and each prerequisite is an edge pointing from the earlier course to the later one. Does that match your understanding?" That sentence buys you a correction, or confirmation, at the cheapest possible moment.
Choosing Between BFS and DFS Out Loud
Once you have a model, the next question is how to walk it. Breadth-first search explores in layers: it visits everything one step away, then everything two steps away, and so on. That layering is why BFS answers "how few steps" questions and finds shortest paths in unweighted graphs. Depth-first search follows one branch as far as it goes before backing up, which suits reachability, connected components, cycle detection and exhaustive exploration.
The decision rule to narrate is simple: if the question contains "minimum number of steps" or "shortest", reach for BFS. If it contains "is there a path", "can all of these be finished", or "group these together", reach for DFS.
Be explicit about the mechanics too, because interviewers listen for it. BFS uses a queue: first in, first out, which is what produces the layer-by-layer order. DFS uses a stack, or recursion, which is a stack in disguise. Both need a visited set. And the visited set is not a detail — it is what keeps the traversal linear rather than exponential. Without it, a graph with cycles lets you revisit the same nodes over and over, and the work blows up. With it, each node is entered once and the total work stays proportional to the size of the graph.
There is an honest caveat worth saying out loud. For weighted graphs, neither plain BFS nor DFS gives shortest paths. If the problem mentions costs or distances, that is your signal to say, "plain BFS will not give the cheapest route here, because it counts edges rather than cost — I would need a different tool for that." Naming the limit of your chosen approach reads as understanding, not weakness.
Cycle Detection and Topological Order
Prerequisite-style questions are the classic place where cycles matter. If course A depends on course B and course B depends on course A, no valid ordering exists. Detecting that is the whole point of the exercise.
For a directed graph, explain the three-colour idea in plain words. Every node is unvisited at the start. While you are exploring, a node is "currently on the recursion stack" — you have entered it but not finished its descendants. Once all its descendants are done, it is finished. If, during a depth-first search, you ever reach a node that is still on the stack, you have found a back edge, and a back edge means a cycle. That is the whole idea, and it is worth saying in exactly those terms rather than reciting colour names.
Topological sort is the constructive version of the same question. Instead of asking "is there a cycle", you ask "give me a valid order". The natural way to describe it: repeatedly take a node that has no remaining prerequisites, place it next, and remove it from the picture. Kahn's algorithm does exactly that, peeling off nodes with zero in-degree. It detects cycles naturally — if the output ends up shorter than the number of nodes, some nodes never became available, which means a cycle blocked them.
Practise saying why the ordering is valid, not just producing it. Interviewers frequently follow up with "why does this order work?" and the answer is a one-sentence argument: every node appears after all the nodes it depends on, because we only ever place a node once nothing it depends on is left.
Grids, Islands and Implicit Graphs
Many graph questions never say the word graph. A grid of land and water is a graph where each cell is a node and adjacency is up, down, left and right. That is the entire translation, and saying it out loud is often the moment the problem becomes easy.
The counting-components pattern follows directly. Scan every cell. When you find an unvisited land cell, that is a new component — increment your count, then run a traversal from that cell that marks the whole connected region as visited. The traversal is ordinary BFS or DFS; the only difference is that neighbours are computed from coordinates rather than read from an adjacency list.
Be ready to explain why you mark cells as visited. If you mark them in place, by overwriting land with water, you save memory but mutate the input — worth flagging. If you use a separate visited structure, you keep the input intact at the cost of extra space. And be ready to explain what happens if you forget: the same region gets counted again and again, and your complexity stops being linear in the number of cells.
Other implicit graphs are worth naming so you start spotting them: word-ladder transformations, where each word is a node and a one-letter change is an edge; state machines, where states are nodes and transitions are edges; and dependency chains between tasks, which behave exactly like the course-prerequisite example wearing different clothes.
The transferable skill is recognising the graph, not memorising the island-counting code.
Talking About Time and Space Complexity
Standard traversal costs O(V + E): every node is entered once and every edge is looked at once. That is the sentence to lead with.
For a grid with R rows and C columns, substitute the concrete sizes. There are R × C cells, and each cell has at most four neighbours, so the traversal is O(R × C). That is usually the answer interviewers expect, and it sounds far more competent than reciting O(V + E) about a grid, because it shows you translated the model back into the problem's own terms.
Space is dominated by the visited set and the queue or the recursion stack, so it is also O(V) in the worst case — every node could be in the structure at once. Two habits make this land well. First, state the complexity in terms of the graph, then substitute the concrete sizes so the number means something. Second, be explicit about the recursion depth risk in DFS: on a large or path-shaped graph, recursion can go as deep as the number of nodes, and if that is a concern you would use an explicit stack instead.
Common Traps and How to Recover Gracefully
These are the mistakes that cost the most, in rough order of frequency.
- Marking a node visited when you dequeue it rather than when you enqueue it. In BFS this lets the same node enter the queue several times, which can duplicate work or, in the wrong graph, loop. Mark on enqueue.
- Treating a directed problem as undirected, or the reverse. This quietly changes the answer. Go back to the three questions — does the relationship point one way or both ways? — and check.
- Assuming the graph is connected when the problem never says so. Always ask whether you need to handle multiple components. If the answer is yes, your traversal belongs inside a loop over all nodes, not around a single start node.
- Reaching for weighted shortest-path machinery on an unweighted graph. If every edge costs the same, plain BFS already gives shortest paths, and the extra machinery is more to explain and more to get wrong.
If you notice a mistake mid-solution, say so plainly. "I marked visited on dequeue there, which is wrong — let me move it to enqueue and re-check the loop." Then fix it and continue. Recovering calmly reads as competence; pretending nothing happened reads as the opposite.
A Practice Routine That Builds Reasoning, Not Recall
Work in three passes. First, model the graph on paper: nodes, edges, direction, weight. Second, narrate the algorithm without writing code — enough that a listener could implement it from your description. Third, implement. The first two passes are where the interview is actually won.
Record yourself solving one graph problem and listen back for the moments you went quiet. Silence is usually where the reasoning was skipped, and those gaps are exactly what an interviewer would have probed.
Rotate problem families deliberately: traversal, connected components, cycle detection, topological ordering, weighted shortest paths. The point is to practise choosing rather than recognising, because recognition only works on problems you have already met.
After each attempt, write one sentence about what signal in the prompt told you which approach to use. Over a few weeks those sentences become your decision rule, and it will be yours rather than borrowed.
If you want structured repetition with feedback on how you explain your reasoning, you can practise with your own material and review it afterwards; our documentation explains how the practice flow is set up. It also helps to read around the topic — for instance, Python Interview Questions: Concepts and Trade-Offs covers the kind of trade-off reasoning that pairs well with graph questions, and the rest of our blog has more on interview preparation.
Putting It Together
The repeatable sequence is short enough to remember under pressure. Translate the story into nodes and edges. Choose a traversal based on the question being asked, and say why. Justify the result — why the ordering is valid, why the count is right. Then state the complexity in concrete terms drawn from the problem itself.
Graph questions reward candidates who think in public. The code is often short; the reasoning is what is being assessed. Keep the honesty rule in mind: this is preparation for doing the work yourself in the room, not a script to lean on during a live interview.
Take one graph problem you have already solved and walk through it aloud again, from a blank page. If you can do that cleanly, you are ready for one you have never seen.
Frequently asked questions
Do I need to memorise graph algorithms for a coding interview?
No. Memorised templates only help once you have already recognised the problem, and recognition is what fails on unfamiliar questions. What helps more is a short reasoning habit: name the nodes, name the edges, decide direction and weight, then choose a traversal because of what the question asks. You will still want to know how BFS, DFS and topological ordering work, but you want to be able to rebuild them from the model rather than recall them by sight.
How do I know whether to use BFS or DFS in a graphs coding interview question?
Read the question for the signal. If it asks for a minimum number of steps or a shortest path in an unweighted graph, use breadth-first search, because it explores in layers. If it asks whether a path exists, whether everything can be finished, or how to group things together, use depth-first search. Say the reason out loud when you choose, and add the caveat that neither plain BFS nor DFS gives shortest paths when edges carry weights.
What is the time complexity of a graph traversal, and how should I say it out loud?
A standard traversal costs O(V + E), because each node is entered once and each edge is looked at once. For a grid with R rows and C columns, substitute the concrete sizes and say O(R × C), since each cell has at most four neighbours. Space is O(V) in the worst case, dominated by the visited set and the queue or recursion stack.
How do I handle a graph problem when the input is a grid instead of an adjacency list?
Translate it first: each cell is a node, and adjacency is up, down, left and right. Then use the same traversal you would use on an adjacency list, except that neighbours are computed from coordinates rather than read from a stored list. For counting components, scan every cell, and when you find an unvisited land cell, increment your count and run a traversal that marks the whole connected region.
What should I do if I realise mid-answer that I chose the wrong approach?
Say so plainly, explain the fix and continue. For example: the graph is weighted, so plain BFS will not give the cheapest route; I need to account for cost instead. Recovering calmly reads as competence, and interviewers generally prefer a candidate who notices and corrects a mistake to one who quietly hopes nobody noticed.
How much graph theory do I actually need for a software engineering interview?
Less than a course, more than a glance. You need to be comfortable naming nodes and edges, distinguishing directed from undirected and weighted from unweighted, and knowing what BFS, DFS, cycle detection and topological ordering are for. Beyond that, the useful skill is translation: turning a story about courses, friends, flights or grids into a model you can reason about out loud. A good way to test that is to take a problem you have already solved and explain your reasoning again without notes, so you can hear where the model, not the code, was doing the work.
Re-explain one solved graph problem out loud, from a blank page.