Unit 1 · Algorithms · Lesson 14 of 24
Graph traversal: BFS, DFS and components
Step 1: Learn the ideas
- Representations: adjacency list, adjacency matrix, edge list, implicit neighbor functions
- BFS and the distance-layer invariant
- Level-by-level BFS and parent pointers for path reconstruction
- Recursive and iterative DFS; recursion-depth limits
- Connected components and flood fill
- Grids as implicit graphs: direction arrays and bounds checks
- Multi-source BFS
- Bipartite checking by two-coloring
- State-space search and bidirectional BFS (awareness)
Why it matters
Graph traversal sits underneath problems that never mention a graph: a grid of cells, words that differ by one letter, accounts that share an email address, services that depend on each other. Interviewers check three things: whether you can see the graph (what the nodes and edges are), whether you choose the traversal that answers the question, and whether your visited bookkeeping is correct. The same ideas appear in systems work as reachability in dependency graphs, the mark phase of garbage collectors, web crawlers and flooding-based broadcast in networks.
Core ideas
Representation. Adjacency lists suit sparse graphs: O(V + E) space and neighbor iteration proportional to degree. A grid needs no explicit graph; generate the neighbors of (r, c) from a direction array with one bounds check. Estimate V and E before coding: all 4-digit lock states form an implicit graph of 10^4 nodes with 8 neighbors each, small enough to search exhaustively, while many board-game state spaces are not.
BFS. A FIFO queue processes vertices in layers: every vertex at distance d leaves the queue before any vertex at distance d + 1. Invariant: the queue holds at most two consecutive distance values, in non-decreasing order. Because every edge has length 1, the first discovery of a vertex happens along a shortest path, so setting dist[v] = dist[u] + 1 at discovery is final. Mark a vertex visited when you enqueue it, not when you dequeue it; otherwise a vertex can enter the queue once per incoming edge, which inflates time and memory and, if distances are written at enqueue time, can overwrite a correct distance with a larger one.
from collections import deque
def bfs(sources, neighbors):
dist = {s: 0 for s in sources} # visited set and distances in one map
queue = deque(sources)
while queue:
u = queue.popleft()
for v in neighbors(u):
if v not in dist: # mark on discovery, not on removal
dist[v] = dist[u] + 1
queue.append(v)
return dist
Multi-source BFS. Seeding the queue with every source at distance 0 gives each vertex its distance to the nearest source in a single O(V + E) pass. It is the same as adding a virtual super-source joined to every real source and subtracting one from the results. A separate BFS per source would cost O(k(V + E)) for k sources.
DFS. DFS follows one path as far as possible, then backtracks; with recursion, the call stack is the stack. It answers reachability and component labeling, and with discovery and finish bookkeeping it detects cycles and produces topological orders (next topic). It does not find shortest paths. Recursive DFS on a 1000 by 1000 grid can reach depth 10^6, far beyond Python's default recursion limit of 1000 and enough to overflow native stacks in other languages, so be able to write the iterative version with an explicit stack.
Components. Loop over all vertices; whenever one is unvisited, start a traversal from it and label everything it reaches. The total is still O(V + E) because each vertex and edge is handled once across all traversals. Counting islands is exactly this on a grid.
Bipartiteness. Two-color with BFS or DFS, giving each neighbor the opposite color; a conflict means an odd cycle. Start a traversal in every component.
Common misconceptions
- "DFS finds shortest paths if I keep the minimum." DFS visits paths in an arbitrary order, and taking minima over all of them is exponential backtracking. Use BFS for unit weights and the shortest-path algorithms for weighted graphs.
- "Marking visited on dequeue is equivalent." At best it wastes work: a vertex can be enqueued once per incoming edge, which multiplies time and memory on grids with many converging paths. At worst, a distance written at enqueue time is overwritten by a longer one. Mark on enqueue.
- "Traversal is O(V) because each vertex is visited once." Every adjacency list is scanned once too, so the bound is O(V + E), which is O(V^2) for dense graphs.
- "One traversal from node 0 covers the graph." Only if the graph is connected. Component counts, bipartite checks and cycle checks must loop over all start vertices.
- "Overwriting the input grid to mark visited is free." It saves memory but destroys the caller's data. Say that you are doing it, or copy, and restore cells when the input must stay intact.
How to approach it
Say the graph out loud before coding: "nodes are cells, edges join 4-neighbors that are both land". Choose the traversal from the question: a minimum number of steps suggests BFS; reachability, grouping or exhaustive exploration suggests DFS or BFS, whichever is simpler to get right. Put neighbor generation in its own function so bounds checks live in one place. Test with an empty grid, a single cell, no land at all, and a disconnected graph. Interviewers at every level expect the O(V + E) analysis; stronger answers also mention recursion depth, the size of an implicit state space, and bidirectional BFS when the branching factor is large, as in word-transformation problems.
Suggested order
- 1Read MIT 6.006 Lecture 9 (Breadth-First Search) for graph representations, the shortest-paths tree and why BFS layers equal distances.
- 2Read MIT 6.006 Lecture 10 (Depth-First Search) up to Full-DFS and graph connectivity, then skim Erickson Ch. 5 (Basic Graph Algorithms) for the "whatever-first search" view that unifies stack, queue and priority-queue traversal.
- 3Write BFS with a distance map and iterative DFS from memory on a small adjacency list, then adapt both to a grid using a direction array.
- 4Solve Number of Islands with both BFS and DFS, then Clone Graph, where the original-to-copy map doubles as the visited set.
- 5Solve Rotting Oranges and 01 Matrix to internalize multi-source BFS, and explain the super-source equivalence aloud.
- 6Solve Surrounded Regions and Pacific Atlantic Water Flow (search inward from the border), then Is Graph Bipartite? and Word Ladder as a large implicit state space.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
MIT 6.006 Introduction to Algorithms (Spring 2020)Start here
MIT OpenCourseWareSection: Lecture 9: Breadth-First Search
Graph representations, BFS layers, the shortest-paths tree and the O(V + E) analysis; continue with Lecture 10 for DFS and connectivity.
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms (Jeff Erickson) with companion lecture notesStart here
Jeff Erickson, University of Illinois Urbana-ChampaignSection: Ch. 5: Basic Graph Algorithms
Representations, generic "whatever-first" search, connected components and flood fill as a graph reduction.
Open(opens in a new tab)Link responded, 5 Oct 2026Competitive Programmer’s Handbook
CSESSection: Ch. 12: Graph traversal
Short implementation-level treatment of DFS, BFS and applications such as connectivity and bipartiteness checks.
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms, 4th Edition booksite
Princeton UniversitySection: 4.1 Undirected Graphs
Tested reference implementations of DFS, BFS, connected components and bipartiteness to compare with your own code.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Before coding each problem, write one line naming the nodes, the edges and the question type (distance, reachability or grouping). Solve the first three with both BFS and DFS where that makes sense and note which version was easier to get right. The later items are review-rotation material: when you revisit traversal, pick one you have not solved yet rather than repeating an old one.
- Number of IslandsLeetCode(opens in a new tab)Not attemptedLeetCode
- Clone GraphLeetCode(opens in a new tab)Not attemptedLeetCode
- Rotting OrangesLeetCode(opens in a new tab)Not attemptedLeetCode
- 01 MatrixLeetCode(opens in a new tab)Not attemptedLeetCode
- Surrounded RegionsLeetCode(opens in a new tab)Not attemptedLeetCode
- Pacific Atlantic Water FlowLeetCode(opens in a new tab)Not attemptedLeetCode
- Is Graph Bipartite?LeetCode(opens in a new tab)Not attemptedLeetCode
- Word LadderLeetCode(opens in a new tab)Not attemptedLeetCode
- Longest Increasing Path in a MatrixLeetCode(opens in a new tab)Not attemptedLeetCode
- Number of ProvincesLeetCode(opens in a new tab)Not attemptedLeetCode
- Shortest Path in Binary MatrixLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why must BFS mark a vertex visited when it is enqueued rather than when it is dequeued?
- Question 2What does multi-source BFS compute, and how is it equivalent to a single-source BFS?
- Question 3When can recursive DFS fail on a valid input, and how do you rewrite it iteratively?
- Question 4How do you count connected components, and why is the total cost still O(V + E)?
- Question 5How do you detect that an undirected graph is not bipartite, and what structure does the conflict reveal?
- Question 6How large is the implicit graph in a word-transformation problem, and how can neighbors be generated efficiently?
You’re done when you can
- Write BFS with a distance map and an iterative DFS from memory in under 10 minutes each, and run both correctly on a disconnected test graph.
- Solve an unseen grid problem (components or multi-source distances) in under 25 minutes without hints.
- Explain in under two minutes why BFS distances are shortest in an unweighted graph and why visited marking happens on enqueue.
- State the time and space complexity of every solved problem in terms of V and E (or rows and columns) without hesitation.
Finish the lesson
Unlocks next: Cycles, topological order and union-find, Shortest paths and their assumptions, Pattern recognition and mixed practice


