Algorithm visualizer

June 6, 2026

Visual Algorithm Debugger: How to Step Through BFS, DFS, and DP Problems

Submitting code and watching it pass is not the same as understanding execution. A visual algorithm debugger shows you what the queue contains after each BFS step, how the DP table fills cell by cell, and exactly where your DFS goes wrong — and why.

There is a gap that most developers hit around the 100-problem mark on LeetCode. You submit code, it passes, and you move on. But when the interviewer says "walk me through your approach," you realize you can describe the high-level idea without being able to trace the execution. You know BFS uses a queue — but you can't say exactly which node is in the queue at step 4, or why the algorithm visits nodes in that specific order.

A visual algorithm debugger closes that gap. Instead of reading code or watching a fixed animation, you pause at any step and inspect the full execution state: queue contents, visited sets, pointer positions, DP table values — everything that the algorithm is maintaining at that exact moment. This article walks through what that looks like for BFS, DFS, and DP, and why it changes how you prepare for interviews.

What static analysis misses

Reading code and understanding execution are different skills. When you read a BFS implementation, you see the loop structure. You know the queue starts with the source node and gets processed level by level. But "knowing" that and being able to state "at this moment the queue contains nodes 3, 7, and 9 and node 2 was just marked visited" are not the same thing.

This distinction matters in coding interviews because you are not evaluated on whether your code compiles — you are evaluated on whether you can reason about its execution. Interviewers ask: "what is the state of your data structure after this step?" and "why does your algorithm visit this node before that one?" Static code reading doesn't train you to answer those questions quickly. Watching execution does.

The same issue appears in debugging. When your BFS returns the wrong shortest path, or your DP table produces an incorrect value, the bug is almost never in the surface logic — it's in a state transition you didn't trace. A visual debugger makes the incorrect transition visible immediately.

What a visual algorithm debugger actually shows you

A visual algorithm debugger is different from a static visualizer. A visualizer plays a predefined animation on a fixed input — you watch someone else's implementation run. A debugger gives you control over your own code's execution:

  • Full state at each step: queue contents in BFS, the recursion call stack in DFS, exact cell values as the DP table fills. Not summarized — the complete snapshot.
  • Data structure changes: when a node gets added to the visited set, when a distance array entry updates, when the sliding window expands or contracts. Each mutation is visible as it happens.
  • Decision points: why the algorithm chose to process node A before node B, why a DFS path got pruned, why a DP recurrence chose one subproblem over another. The decision logic is rendered, not just the outcome.
  • Step controls: pause, step forward, step back, jump to any moment. You're not watching a video — you're operating the execution.

The result is that you build a mental model of execution, not just of code structure. After stepping through BFS ten times, you don't need to run the code to know what the queue contains after each level — you've internalized it.

Stepping through BFS: the queue in motion

BFS (breadth-first search) explores a graph level by level, using a queue to track which nodes to process next. The algorithm is simple to describe — the bug surface is in queue state management: when you enqueue neighbors, when you mark them visited, and what happens when you dequeue and process.

Here is what a visual debugger shows you at each step of BFS on a small graph (source = 0, edges: 0→1, 0→2, 1→3, 2→3):

Step 1 — Initialize

queue    = [0]
visited  = {0}
level    = 0

Step 2 — Dequeue 0, enqueue neighbors 1 and 2

queue    = [1, 2]
visited  = {0, 1, 2}
level    = 1
current  = 0  →  neighbors: [1, 2]

Step 3 — Dequeue 1, enqueue neighbor 3

queue    = [2, 3]
visited  = {0, 1, 2, 3}
level    = 1→2
current  = 1  →  neighbors: [3]  (0 already visited)

Step 4 — Dequeue 2, neighbor 3 already visited

queue    = [3]
visited  = {0, 1, 2, 3}
current  = 2  →  neighbors: [3]  (already visited, skip)

The most common BFS bug — marking nodes visited when you dequeue instead of when you enqueue — is invisible when you just read the code. The queue looks correct in your head. In a visual debugger, you immediately see the queue fill with duplicate entries: node 3 gets enqueued twice because it wasn't marked visited until after both neighbors added it.

For a deeper look at BFS patterns and when to apply them, see the graph algorithms for coding interviews guide.

Stepping through DFS: where the recursion stack hides bugs

DFS bugs are harder to find than BFS bugs because the state lives in the call stack — a structure that's invisible unless you explicitly track it. When your DFS returns the wrong count, or doesn't backtrack correctly, the bug is almost always in how state is shared across recursive calls.

A visual debugger renders the call stack as a live data structure. Here is the state during a DFS exploring paths in a graph (source = 0, adjacency: 0→[1,2], 1→[3], 2→[3]):

Call 1 — dfs(0)

call stack   = [ dfs(0) ]
path         = [0]
visited      = {0}

Call 2 — dfs(1) from dfs(0)

call stack   = [ dfs(0), dfs(1) ]
path         = [0, 1]
visited      = {0, 1}

Call 3 — dfs(3) from dfs(1)

call stack   = [ dfs(0), dfs(1), dfs(3) ]
path         = [0, 1, 3]
visited      = {0, 1, 3}
→ reached target, record path [0,1,3]

Backtrack — return to dfs(1), then dfs(0)

call stack   = [ dfs(0) ]
path         = [0]          ← restored after backtrack
visited      = {0}          ← 1 and 3 unmarked if using backtracking

The backtrack step is where most DFS bugs live. If you forget to unmark nodes from the visited set when returning (in problems that need all paths, not just one), the second path from node 2 never gets explored. A visual debugger makes the visited set state visible at every step, so the missing unmark is immediately obvious.

This is especially important for backtracking problems (combinations, permutations, subsets) where the entire correctness of the solution depends on what gets added to and removed from the current path at each recursive call.

Stepping through DP: watching the table fill

Dynamic programming bugs are some of the hardest to catch by reading code because the recurrence relation looks correct on paper but produces wrong values in practice. The issue is almost always in base cases, index offsets, or which previous cells a state depends on.

A visual debugger renders the DP table as it fills — you see each cell computed, which previous cells it reads from, and what value it stores. Here is a simplified trace of the Longest Common Subsequence problem (s1 = "ace", s2 = "abcde"):

DP table — step by step fill (rows = s1, cols = s2)

     ""  a  b  c  d  e
""  [ 0   0  0  0  0  0 ]
a   [ 0   1  1  1  1  1 ]   ← dp[1][1] = dp[0][0]+1 = 1 (s1[0]==s2[0])
c   [ 0   1  1  2  2  2 ]   ← dp[2][3] = dp[1][2]+1 = 2 (s1[1]==s2[2])
e   [ 0   1  1  2  2  3 ]   ← dp[3][5] = dp[2][4]+1 = 3 (s1[2]==s2[4])

When the recurrence is wrong — for example, reading dp[i-1][j] instead of dp[i-1][j-1] — you see the cell value diverge from expectation the moment it computes. You know exactly which cell triggered the wrong propagation and why.

For the full breakdown of DP patterns and common recurrences, see the guide to dynamic programming explained with 5 patterns.

Why this matters in coding interviews

In a technical interview, the code you write is almost secondary to how you reason about it. The questions that trip people up are not "can you implement BFS?" — almost everyone can write the loop. They are:

  • "What is in your queue right now?"
  • "Why does your algorithm visit node 4 before node 5?"
  • "What happens to your DP state if I change this constraint?"
  • "Your output is wrong on this input — walk me through where your logic breaks."

These questions require execution-level understanding, not just code-level understanding. The only way to build execution-level understanding is to have watched algorithms execute — not just read them. A developer who has stepped through BFS 20 times in a visual debugger can answer "what's in the queue right now?" without writing a single line of code. They've internalized the execution model.

This is also why debugging speed matters in interviews. When your first attempt produces the wrong output, the time it takes to identify the bug separates candidates. Developers trained on visual execution know where to look — they trace the state in their head in the same way the debugger showed them.

How Expora's visual algorithm debugger works

Expora's visual algorithm debugger is built around two modes. In the first mode, you step through a reference implementation — the canonical version of BFS, DFS, Dijkstra, sliding window, binary search, or DP — and see the full execution state at every step. This builds the initial mental model.

In the second mode, you write your own code in the integrated editor, run it, and step through your execution side by side with the reference. When your output diverges, you see exactly which step produced the wrong state. You're not guessing — you're observing the divergence directly.

Algorithms covered in the debugger

BFS — level-order, shortest path
DFS — recursive, iterative, backtracking
Dijkstra — weighted shortest path
Dynamic Programming — 1D and 2D tables
Sliding Window — expand/contract
Two Pointers — sorted arrays, partitions
Binary Search — 3 templates
Graph algorithms — Bellman-Ford, Kruskal

The debugger is integrated with the coding notebook — after stepping through the reference, you open a problem from your LeetCode history, write your solution, and debug it visually. The Chrome extension imports the problem and your code in one click, so the friction of "let me set this up" doesn't interrupt the learning flow. See the full visual algorithm debugger.

Frequently asked questions

What is a visual algorithm debugger?

A visual algorithm debugger lets you step through an algorithm's execution and see exactly what happens at each step — queue contents in BFS, the call stack in DFS, DP table values as they compute — all rendered visually. Unlike a static animation that plays a predefined sequence, a debugger gives you full control: pause at any step, inspect the current state, step backward, and run your own code to debug it visually.

How is a visual debugger different from an algorithm visualizer?

An algorithm visualizer shows a pre-built animation of a known implementation on fixed input — you watch, but you don't control the code. A visual algorithm debugger lets you execute your own code and observe its state at every step. When your solution diverges from the correct behavior, the visual makes the exact step and state where the error occurred immediately visible. Expora provides both: reference visualizers to build intuition, and a debugger to validate and debug your own implementation.

Why do I keep getting BFS wrong even though I understand the concept?

The most common BFS implementation bug is marking nodes visited when you dequeue rather than when you enqueue. This allows duplicate entries in the queue, leading to incorrect level counts or redundant processing. The bug is invisible when reading code because the logic "looks right" — both approaches process each node once in simple graphs. In a visual debugger you see the queue fill with duplicates immediately. The second common bug is not initializing the visited set before enqueuing the source node, which causes infinite loops on cyclic graphs.

How do I debug a dynamic programming solution that gives wrong answers?

DP bugs almost always fall into three categories: (1) wrong base case — the initial cells of the table are set incorrectly, causing all downstream values to be off, (2) wrong recurrence — the formula reads from the wrong previous cells, often an off-by-one in the index, and (3) wrong iteration order — cells are computed before their dependencies are ready. A visual debugger solves all three: you see the table fill cell by cell, which cells each computation reads from, and the exact value that diverges from expectation. Print-debugging a DP table gives you the same values, but without the visual layout showing dependencies it's much harder to identify the root cause.

When should I use step-through debugging vs just running the algorithm?

Use step-through debugging in three situations: (1) when learning a new algorithm — stepping through the reference implementation builds the mental model faster than reading explanations, (2) when your solution fails on a test case — running the algorithm tells you the wrong output, stepping through shows you which state transition produced it, and (3) when preparing for interviews — practicing narrating execution state out loud while stepping through trains you to answer "walk me through your approach" questions under pressure.

Explore more

Expora

Step through algorithms, not just read them

Expora's visual debugger shows queue state, call stacks, and DP tables executing step by step — so you understand execution, not just code.

No credit card required · Early access