Skip to main content

CS Glossary

Depth-First Search (DFS)

A graph/tree traversal that explores as deep as possible along each branch before backtracking, using recursion or a stack.

Time: O(V + E) where V = vertices, E = edges Space: O(V) for the visited set; O(H) for recursion stack (H = height of tree)

Overview

Depth-First Search (DFS) explores a graph or tree by going as deep as possible along each branch before backtracking. It is naturally implemented with recursion (the call stack acts as the implicit stack) or with an explicit stack data structure. DFS is essential for problems involving tree traversals, cycle detection, connected components, topological sorting, and path finding.

How It Works

  1. 1 Start at the source node and mark it as visited.
  2. 2 Explore one unvisited neighbor recursively (or push onto stack).
  3. 3 If no unvisited neighbors remain, backtrack to the previous node.
  4. 4 Repeat until all reachable nodes are visited.
  5. 5 For trees: pre-order (root, left, right), in-order (left, root, right), post-order (left, right, root).

Complexity Analysis

Time: O(V + E) where V = vertices, E = edges Space: O(V) for the visited set; O(H) for recursion stack (H = height of tree)

Each vertex and edge is visited once. The recursion depth equals the height of the tree/graph — O(log n) for balanced trees, O(n) for skewed trees. The iterative version using an explicit stack has the same complexity.

When to Use

  • →Tree traversals (pre-order, in-order, post-order)
  • →Detecting cycles in a graph
  • →Finding connected components
  • →Topological sorting (with post-order DFS)
  • →Path existence problems ("is there a path from A to B?")
  • →Solving puzzles with backtracking (N-Queens, Sudoku)

Common Mistakes

  • ⚠Forgetting to mark nodes as visited before recursive calls (causes infinite loops)
  • ⚠Not handling disconnected components (need to loop over all nodes)
  • ⚠Confusing pre-order/in-order/post-order traversal order
  • ⚠Stack overflow from deep recursion on large inputs (use iterative DFS)
  • ⚠Modifying the graph while iterating (breaks adjacency lists)

Code Examples

List<Integer> dfs(List<List<Integer>> graph, int node, Set<Integer> visited) {
    visited.add(node);
    List<Integer> result = new ArrayList<>();
    result.add(node);
    for (int neighbor : graph.get(node)) {
        if (!visited.contains(neighbor)) {
            result.addAll(dfs(graph, neighbor, visited));
        }
    }
    return result;
}

Related Patterns

Practice Problems

Frequently Asked Questions

What is DFS and how is it different from BFS?
DFS (Depth-First Search) explores as deep as possible along each branch before backtracking, using recursion or a stack. BFS explores level by level using a queue. DFS uses less memory for deep graphs and is better for cycle detection, topological sort, and path problems. BFS finds shortest paths in unweighted graphs. Choose DFS for depth-oriented problems, BFS for breadth/level problems.
When should I use DFS vs BFS in coding interviews?
Use DFS when: the problem involves trees (most tree problems are naturally recursive), cycle detection, topological sort, connected components, backtracking, or "does a path exist" questions. Use BFS when: you need the shortest path in an unweighted graph, level-order traversal, minimum steps/moves, or level-by-level processing.
What are pre-order, in-order, and post-order traversals?
Pre-order: visit root first, then left subtree, then right subtree (useful for copying a tree). In-order: visit left subtree, then root, then right subtree (gives sorted order for BSTs). Post-order: visit left subtree, then right subtree, then root (useful for deleting a tree or computing directory sizes). All three are O(n) time.

Master this concept with practice

Browse all patterns and problems to build systematic interview intuition.

Buy me a coffee
Daily Practice
0/0