LeetCopilot Logo
LeetCopilot
Home/Blog/How to Choose Between BFS and DFS on LeetCode: A Beginner-Friendly Decision Guide

How to Choose Between BFS and DFS on LeetCode: A Beginner-Friendly Decision Guide

LeetCopilot Team
Nov 26, 2025
15 min read
LeetCodeBFSDFSGraphsTreesInterview Prep
Every graph or tree problem feels like a coin flip between BFS and DFS. This guide gives you a practical, pattern-based way to choose the right traversal for LeetCode interviews.

You open a tree or graph problem on LeetCode and immediately think:

“Is this BFS or DFS?”

You vaguely remember rules from tutorials—“BFS for shortest path, DFS for recursion”—but in real problems the lines blur. You end up guessing, switching approaches halfway through, or trying both and getting lost in bugs.

This guide gives you a practical, experience-based decision framework for choosing between BFS and DFS on LeetCode, with clear examples, diagrams, and interview-focused strategies.

TL;DR

  • Use BFS when you care about distance by steps/levels, the shortest path in an unweighted graph, or processing in layer order.
  • Use DFS when you care about exploring full paths, backtracking, or structural properties like “is there a path/cycle/subtree satisfying X?”.
  • Many problems can be solved with either; the better choice is the one that keeps your state, code, and reasoning simplest.
  • Beginners often misuse DFS for shortest path, forget visited semantics in BFS/DFS, or mix recursion and mutable state incorrectly.
  • You’ll learn a concrete decision checklist, visual mental models, and implementation templates to make BFS/DFS choices feel systematic instead of random.

Beginner-Friendly Intuition: How BFS and DFS “Think”

BFS: Wave-by-wave exploration

Breadth-first search explores nodes in layers:

text
Level 0:       A
             /   \
Level 1:    B     C
           / \   / \
Level 2:  D   E F   G

At each step, BFS processes all nodes at the current distance before moving deeper:

  • Level 0: A
  • Level 1: B, C
  • Level 2: D, E, F, G

It uses a queue and is ideal when:

  • You need the shortest path (fewest edges) in an unweighted graph.
  • You care about “distance in steps” (e.g., minimum moves, minimum days).
  • You want the answer as soon as the first valid node is found.

DFS: Dive-deep exploration

Depth-first search goes as deep as possible along one path, then backtracks:

text
A → B → D (dead end) → backtrack → E → backtrack → C → F → G

It uses a stack (often via recursion) and is ideal when:

  • You need to inspect or build entire paths.
  • You care about structure: cycles, connectivity, subtree properties.
  • You are doing backtracking: generating combinations, permutations, paths.

Step-by-Step Decision Framework

When you see a tree or graph problem, run this checklist:

Question 1: Do we care about shortest path / minimum steps?

If the problem asks for:

  • Shortest path in an unweighted graph or grid
  • Minimum number of moves / operations / transformations
  • Minimum number of edges between two nodes

Then default to BFS.

Examples:

  • “Minimum steps to transform word A to word B.”
  • “Shortest path in a maze.”
  • “Minimum number of operations to reach target.”

Question 2: Do we need all possible paths or combinations?

If you need:

  • All paths from source to target
  • All combinations / permutations / subsets
  • To explore many possibilities and backtrack

Then default to DFS / backtracking.

Examples:

  • “Find all paths from node 0 to node N-1.”
  • “Generate all valid parentheses strings of length 2n.”
  • “Find all paths that sum to target in a tree.”

Question 3: Is the graph/tree huge with simple yes/no answers?

If you only need:

  • “Does any valid path exist?”
  • “Is this graph connected?”
  • “Does this graph contain a cycle?”

Then either BFS or DFS works. In practice:

  • Use DFS when recursion is natural and depth isn’t too large.
  • Use BFS when you want predictable memory and iteration.

At this point, you can choose whichever keeps the state simpler.

Question 4: Are we layering by time/rounds?

Problems that simulate time or rounds often map to BFS:

  • “Number of minutes until all oranges rot.”
  • “Min days to infect all nodes in a network.”
  • “Spread from multiple sources at once.”

Think of BFS as simulating a multi-source wave. This aligns well with AI-guided LeetCode practice that visualizes levels step by step.

Visual Examples You Can Sketch in Interviews

Example 1: Shortest path in a grid → BFS

Problem sketch:

“Given a grid of 0s and 1s, find the shortest path from top-left to bottom-right, moving only up/down/left/right through 0s.”

Draw the grid and BFS layers:

text
Start at (0,0)

Layer 0: (0,0)
Layer 1: neighbors of (0,0)
Layer 2: neighbors of all nodes in layer 1
...

As soon as you reach the target cell, you know you’ve found the shortest path (fewest steps).

Example 2: Count islands → DFS or BFS

Problem sketch:

“Count the number of islands in a grid.”

You don’t care about shortest path or distances. You care about exploring all reachable cells from each land cell.

You can:

  • Use DFS to recursively explore each connected component.
  • Or use BFS with a queue to explore neighbors.

Both work—choose the one that’s easier for you to implement correctly.

Code Example: BFS vs DFS Templates for a Grid

Let’s compare clean, minimal templates in TypeScript for a grid problem like “count number of islands”.

BFS template

typescript
function bfs(grid: string[][], startRow: number, startCol: number): void {
  const rows = grid.length;
  const cols = grid[0].length;
  const queue: [number, number][] = [[startRow, startCol]];

  grid[startRow][startCol] = "0"; // mark visited

  const directions = [
    [1, 0],
    [-1, 0],
    [0, 1],
    [0, -1],
  ];

  while (queue.length > 0) {
    const [r, c] = queue.shift()!;

    for (const [dr, dc] of directions) {
      const nr = r + dr;
      const nc = c + dc;
      if (
        nr >= 0 &&
        nr < rows &&
        nc >= 0 &&
        nc < cols &&
        grid[nr][nc] === "1"
      ) {
        grid[nr][nc] = "0"; // mark visited
        queue.push([nr, nc]);
      }
    }
  }
}

DFS template

typescript
function dfs(grid: string[][], r: number, c: number): void {
  const rows = grid.length;
  const cols = grid[0].length;

  if (r < 0 || r >= rows || c < 0 || c >= cols || grid[r][c] !== "1") {
    return;
  }

  grid[r][c] = "0"; // mark visited

  dfs(grid, r + 1, c);
  dfs(grid, r - 1, c);
  dfs(grid, r, c + 1);
  dfs(grid, r, c - 1);
}

Both variants:

  • Use a visited mechanism (mutating the grid).
  • Explore all connected neighbors.
  • Can be plugged into a double loop counting islands.

Practical Preparation Strategies

1. Build a tiny BFS/DFS note for yourself

In your notes or DSA learning path, keep:

  • A 10–15 line BFS template.
  • A 10–15 line DFS (recursive) template.
  • 2–3 example problems where each shines.

Review this before graph-heavy interviews to keep syntax fresh.

2. Classify 20 problems by traversal type

Pick 20 LeetCode problems involving trees/graphs and label them:

  • BFS, DFS, or “either”.
  • Why you chose that pattern (shortest path vs structure vs enumeration).

This helps you recognize patterns quickly instead of guessing the approach each time.

3. Practice explaining your choice out loud

In interviews, don’t just say “I’ll use BFS.” Say:

“Because we need the shortest path in an unweighted graph, BFS over levels is a natural fit.”

Or:

“We only need to know whether any path exists, and recursion is natural on trees, so I’ll use DFS.”

A coding interview guide mindset helps you frame these justifications clearly.

4. Use interactive tools when stuck

When debugging traversal bugs, tools like LeetCopilot can support you by showing queue/stack contents step by step, helping you see where your visited logic or neighbor enumeration goes wrong.

Common Mistakes to Avoid

Mistake 1: Using DFS for shortest path in unweighted graphs

DFS can accidentally find a path that isn’t the shortest.

Fix: If the question is explicitly about “fewest steps” or “shortest path” without edge weights, default to BFS.

Mistake 2: Forgetting visited semantics

Symptoms:

  • Infinite loops on cyclic graphs.
  • Re-counting nodes / islands.

Fix: Always ask:

  • Where do I mark nodes as visited?
  • Do I mark upon enqueue (BFS) or upon dequeue, or at recursion entry (DFS)?

Be consistent.

Mistake 3: Blowing the recursion stack with DFS

Some inputs (deep trees, long chains) can cause stack overflow.

Fix:

  • Use an explicit stack for DFS instead of recursion when depth might be large.
  • Or choose BFS if it keeps depth shallower and implementation cleaner.

Mistake 4: Overcomplicating the state

Beginners often mix too much state into their traversal (path lists, counts, flags) in a way that’s hard to reason about.

Fix: Separate:

  • Core traversal (queue/stack + visited).
  • Problem-specific state (distance array, parent pointers, path sums).

FAQ

Q1: Can I always use BFS instead of DFS?
Not always. BFS can be more memory-heavy on wide graphs, and recursion-based DFS is often more natural for tree problems and backtracking. Use BFS for shortest paths and layer-based logic; use DFS when exploring full paths or structural properties.

Q2: How do I know if a problem is really a graph problem?
If you can think of elements as nodes with relationships (neighbors, prerequisites, edges), treat it as a graph. Even grids and course schedules are often graphs in disguise.

Q3: Is recursion bad in interviews?
No. Recursion is fine, especially for tree problems, as long as you handle base cases and stack depth safely. Just be ready to explain time/space complexity, including recursion stack space.

Q4: What should I practice before BFS/DFS-heavy interviews?
Do a focused week on trees/graphs: level order traversal, number of islands, shortest path in grid, cycle detection, and topological sort. Tools like mock interview simulator can then stress-test your traversal reasoning under time pressure.

Q5: How do I debug traversal bugs efficiently?
Log or visualize the queue/stack and visited set for small test cases. Check whether nodes are visited multiple times or never visited at all. Using an AI-guided LeetCode practice tool to step through state transitions can accelerate this feedback loop.

Conclusion

Choosing between BFS and DFS on LeetCode doesn’t have to be a coin flip.

The core guidelines:

  • BFS for shortest paths, distances, and layer-by-layer simulations.
  • DFS for path exploration, backtracking, and structural checks.
  • Either is acceptable when the problem doesn’t care about distance—pick the one that makes your state and code simplest.

With a clear decision framework, a couple of small templates, and deliberate practice, you’ll stop guessing and start choosing traversals like a confident engineer rather than a nervous test-taker.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Articles