BFS · Pattern Visualizer

Understand the Pattern

11 problems · 6 pattern flavors · guided walkthroughs + live animations
Before choosing BFS or DFS — what data structure are you looking at?
The first step in any problem is recognizing the underlying structure. The algorithm follows from that.
Mental checklist — read the problem and ask:
Decision flowchart — which pattern?
SAY ALOUD — Your opening move in any problem
"Before writing any code, I identify the data structure. Is the input a grid? A tree? A graph with dependencies? A set of choices to combine? That tells me the pattern — BFS for grids and shortest paths, DFS for trees and nested structures, topological BFS for dependencies, state-space BFS for combinations."
Number of Islands · LC 200 Step 1 of 6
step 1 / 6
🏝️ Number of Islands — Interactive Deep Dive BFS visualizer · line-by-line Java · Why BFS? · Complexity →
Minimum Knight Moves · LC 1197 Step 1 of 5
step 1 / 5
What actually changes between the two grid problems?
Islands · LC 200
  • State: (row,col) in char grid
  • Neighbors: 4 cardinal dirs
  • Visited: boolean grid
  • Trigger: every unvisited '1'
  • Goal: flood + count islands
  • Return: island count
vs
Knight · LC 1197
  • State: (row,col) board position
  • Neighbors: 8 L-shaped jumps
  • Visited: dist map
  • Trigger: single BFS from (0,0)
  • Goal: first arrival = min moves
  • Return: dist[target]
✦ Identical in both
Loop: while queue: r,c = queue.popleft()
Neighbors: for dr,dc in dirs: nr,nc = r+dr,c+dc
Guard: bounds check + not visited before enqueue
Knight Moves is Islands with 8 L-shaped offsets instead of 4, returning a distance instead of a count. The loop body is copy-paste.
Coming soon
Coming soon
Course Schedule · LC 207Step 1 of 5
step 1 / 5
Course Schedule II · LC 210Step 1 of 4
step 1 / 4
207 vs 210 — one extra line is all it takes
Course Schedule · 207
  • Goal: can all courses finish?
  • Track: count completed
  • Return: completed == n
+1 line
Course Schedule II · 210
  • Goal: what order to take them?
  • Track: append pop to result[]
  • Return: result or []
✦ Identical in both
Build graph: adj list + in-degree array
Seed queue: all nodes with indegree==0
BFS loop: pop → decrement neighbors → enqueue when they hit 0
Cycle detection: queue empties before all nodes processed
LC 210 is LC 207 with result.append(course) inside the loop. That's the entire diff.
Coming soon
Coming soon
Letter Combinations · LC 17Step 1 of 5
step 1 / 5
Brace Expansion · LC 1087Step 1 of 5
step 1 / 5
Letter Combinations vs Brace Expansion — same BFS, different token source
Letter Combos · 17
  • Input: digit string
  • Tokens: phone map per digit
  • Branch: 3–4 letters each
  • Return: all combos
same idea
Brace Expansion · 1087
  • Input: brace expression
  • Tokens: parsed groups/chars
  • Branch: 1 or N per token
  • Return: sorted result
✦ Identical in both
State is a partial string, not a position
One BFS level = one token — extend each string by that token's letters
No visited set — partial strings are unique by construction
Both are BFS over a string-building state space. Brace Expansion adds a parse step and a sort. The BFS body is identical.
Coming soon
Coming soon
Path Sum · LC 112Step 1 of 5
step 1 / 5
Flatten Nested List Iterator · LC 341Step 1 of 5
step 1 / 5
Path Sum vs Flatten — same DFS, different data structure
Path Sum · 112
  • Structure: binary tree
  • DFS: recursive calls
  • Neighbors: left, right children
  • Goal: root-to-leaf sum
vs
Flatten · 341
  • Structure: nested lists
  • DFS: explicit stack
  • Neighbors: list contents
  • Goal: iterate integers
✦ Shared with grid DFS
Depth-first: go deeper before backtracking
Boundary check: null = off the edge
Process + recurse: handle current node, then explore children
Path Sum uses recursive DFS (call stack). Flatten uses an explicit stack (same pattern, you manage the stack yourself). Both are DFS on a tree — just like grid DFS with 2 children instead of 4 neighbors.
Coming soon
Coming soon
Implement Trie · LC 208Step 1 of 5
step 1 / 5
How Trie traversal connects to BFS/DFS on a grid
Islands · Grid DFS
  • Node: grid cell (i,j)
  • Neighbors: 4 directions
  • Visited: boolean[][]
  • Walk: explore all paths
vs
Trie · LC 208
  • Node: TrieNode (char pos)
  • Neighbors: 26 children (a-z)
  • Visited: node existence
  • Walk: follow one path
✦ Identical in both
Depth-first traversal: go one step deeper each iteration
Boundary check: In a grid, going out of bounds stops DFS. In a tree, hitting a null child is the same thing — you\'ve gone past the edge, so stop and backtrack
Marking: node creation = visited flag — same concept
A Trie is a tree with 26 children per node instead of 4 grid neighbors. insert() is DFS that creates nodes. search() is DFS that follows them. Same depth-first walk.
Coming soon
Coming soon
Valid Sudoku · LC 36Step 1 of 4
step 1 / 4
Rotate Image · LC 48Step 1 of 4
step 1 / 4
Same outer loop as Number of Islands — different inner action
Valid Sudoku · 36
  • Grid: fixed 9×9
  • Skip: '.' (empty)
  • Action: validate row/col/box
  • Track: HashSet (seen digits)
vs
Rotate Image · 48
  • Grid: n×n matrix
  • Skip: lower triangle (j<i)
  • Action: transpose + reverse
  • Track: none (in-place swap)
✦ Shared with Number of Islands
Nested for-loop scanning every cell in a 2D grid
Skip condition: irrelevant cells are skipped (water/'.'/ lower triangle)
Per-cell action: process relevant cells with a specific operation
The nested for-loop scanning a grid is the same skeleton as Number of Islands. Instead of triggering BFS, you validate constraints (Sudoku) or swap elements (Rotate). Same scan, different action.
Coming soon
Coming soon