DEV Community

Timevolt
Timevolt

Posted on

May the BFS Be With You: Finding Shortest Paths in Unweighted Graphs

The Quest Begins (The "Why")

I still remember the first time I faced a graph‑based interview question. The interviewer drew a maze on the whiteboard and asked, “How would you find the fewest steps from the entrance to the exit?” My brain went into overdrive: I tried recursion, I tried backtracking, I even thought about Dijkstra’s algorithm (overkill for an unweighted grid, I later realized). After a painful 20‑minute struggle, I walked out feeling like I’d just lost a boss fight in Dark Souls without ever landing a hit.

That frustration sparked a quest: understand Breadth‑First Search (BFS) not just as a recipe, but as the underlying reason it guarantees the shortest path in an unweighted graph. Once I grasped the why, the algorithm stopped feeling like a magic incantation and started feeling like a reliable sword I could swing whenever I needed to level‑up my problem‑solving game.

The Revelation (The Insight)

So why does BFS work? Imagine you’re standing at a party and you want to meet everyone who is exactly k introductions away from you. You first greet everyone you know directly (distance 1), then you ask those people to introduce you to their friends (distance 2), and you keep expanding outward. You never jump ahead to someone three hops away before you’ve finished all the two‑hop connections, because that would risk missing a shorter route.

BFS does exactly that with a queue:

  1. Start at the source node, mark it visited, and enqueue it.
  2. Dequeue the front node, explore all its neighbors.
  3. Enqueue any neighbor that hasn’t been visited yet, marking it visited and storing the distance (or predecessor) from the source.
  4. Repeat until the queue is empty.

Because the queue processes nodes in the order they were discovered, nodes are visited in non‑decreasing order of their distance from the source. The first time we dequeue the target node, we have explored all paths of length ≤ d‑1 and just found a path of length d — guaranteeing it’s the shortest possible. No need for priority queues, no need for fancy heuristics; just a simple FIFO line.

The intuition clicked for me when I visualized the wavefront expanding like ripples in a pond. Each ripple represents one more edge traversed, and the moment the ripple hits the target, we know we’ve used the minimum number of stones (edges) to get there.

Wielding the Power (Code & Examples)

Let’s turn that insight into code. Below is a compact Python implementation that returns the shortest path length (or -1 if unreachable) and also reconstructs the actual path.

from collections import deque
from typing import List, Tuple, Optional

def bfs_shortest_path(
    graph: List[List[int]], start: int, goal: int
) -> Tuple[Optional[int], List[int]]:
    """
    Returns (distance, path) from start to goal in an unweighted graph.
    If goal is unreachable, returns (None, []).
    """
    n = len(graph)
    visited = [False] * n
    parent = [-1] * n          # to rebuild the path
    q = deque([start])
    visited[start] = True

    while q:
        node = q.popleft()
        if node == goal:               # we found the shortest path
            break
        for neigh in graph[node]:
            if not visited[neigh]:
                visited[neigh] = True
                parent[neigh] = node   # remember how we reached neigh
                q.append(neigh)

    if not visited[goal]:
        return None, []                # unreachable

    # reconstruct path
    path = []
    cur = goal
    while cur != -1:
        path.append(cur)
        cur = parent[cur]
    path.reverse()                     # from start to goal
    distance = len(path) - 1
    return distance, path
Enter fullscreen mode Exit fullscreen mode

Real‑World Interview Flavors

Problem 1 – Word Ladder (LeetCode 127)

Given beginWord, endWord, and a list of allowed words, each step you may change exactly one letter, and the intermediate word must exist in the list. Find the length of the shortest transformation sequence.

Why BFS? Each word is a node; edges connect words that differ by one letter. All edges have equal weight (one transformation). BFS gives the minimal number of steps directly.

Problem 2 – Rotting Oranges (LeetCode 994)

In a grid, fresh oranges (1) become rotten (2) each minute if adjacent to a rotten one. Determine the minutes until no fresh orange remains, or -1 if impossible.

Why BFS? All initially rotten oranges are sources with distance 0. The wave of rotting spreads uniformly; BFS processes each “minute” layer by layer, yielding the exact time needed.

Common Traps (The “Traps” to Avoid)

Trap What Happens How to Avoid
Using a stack instead of a queue You get DFS, which may find a path but not necessarily the shortest one. Remember: BFS = queue (FIFO). If you catch yourself using pop() (LIFO), switch to popleft().
Forgetting to mark nodes visited when enqueuing You can enqueue the same node multiple times, blowing up complexity to O(V·E) and causing infinite loops in cyclic graphs. Mark visited[neigh] = True immediately when you push it onto the queue.
Assuming weighted edges Applying BFS to a weighted graph gives wrong answers; you’d need Dijkstra or A*. Verify that every edge has the same cost (usually 1) before reaching for BFS.

Why This New Power Matters

Armed with BFS, you can now:

  • Solve grid‑based puzzles (maze escape, flood fill, shortest knight moves) in linear time.
  • Tackle social‑network questions like “degrees of separation” or “friend‑suggestion” with a simple breadth‑first expansion.
  • Ace interview rounds where the interviewer expects you to recognize an unweighted shortest‑path scenario instantly — no more frantic flipping through algorithm sheets.

The best part? BFS runs in O(V + E) time and O(V) space. Every node and edge is touched at most once, making it scalable enough for massive graphs (think crawling the web or analyzing a game map) while still being simple enough to write on a whiteboard in under five minutes.

Imagine you’re back in that interview room, the whiteboard blank, the interviewer smiling. You sketch a quick queue, label the start node, and watch the wavefront ripple outward. When you declare the distance and reconstruct the path, you see a flicker of surprise — then a nod of approval. That’s the moment you realize you’ve leveled up from “I hope I remember the algorithm” to “I own this tool.”

Your Turn – A Mini Quest

Pick any of the two problems above (Word Ladder or Rotting Oranges) and implement BFS in your favorite language. Try to add a small twist: for Word Ladder, also return one actual transformation ladder; for Rotting Oranges, output the grid state after each minute. Share your solution in the comments or tweet it with #BFSQuest — I’d love to see how you wield the power!

Now go forth, spread those ripples, and may the BFS be with you. 🚀

Top comments (0)