← All problems

Coding Prep

Word Ladder

BFS on an implicit graph: each word is a node, edges connect words differing by one character - BFS finds the shortest transformation sequence in O(n * L^2) time.

hardFree~25 min

Problem

Code deployment pipelines sometimes require staged rollouts where each intermediate configuration must be a valid known state. The word ladder problem models this: given a start configuration and target, find the shortest sequence of one-step changes where each intermediate state is valid. Each step changes exactly one character and the result must appear in the allowed-states dictionary.

beginWord = "hit", endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
→ 5  ("hit" → "hot" → "dot" → "dog" → "cog")
 
beginWord = "hit", endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
→ 0  (endWord not reachable)

Solution

Approach: BFS over an implicit graph where words differing by one letter are neighbors.

We never build the graph explicitly - instead we generate a word's neighbors on the fly. For each word popped from the queue, we walk every character position i and try all 26 letters, forming a candidate with word[:i] + chr(ord('a') + j) + word[i+1:]. A candidate is a real edge only if it appears in word_set (the dictionary, stored as a set for O(1) membership). BFS explores all words at sequence length k before any at k+1, so the first time we generate end_word we have reached it in the fewest transformations - that is why we can return length + 1 the instant a candidate matches the target.

We track length in each queue tuple, starting at (begin_word, 1) since the sequence length counts both endpoints. Visited words are recorded in a visited set so a word is enqueued only once, preventing cycles and redundant expansion. On the classic hit -> cog example, BFS discovers hot at length 2, dot/lot at 3, dog/log at 4, and matches cog at length 5.

Edge cases: if end_word is not in word_set, no sequence can end there, so we return 0 up front. begin_word need not be in the dictionary - it is enqueued directly. If the queue drains without producing end_word, we return 0.

Complexity: O(n * L^2) time where n is the dictionary size and L the word length - each word spawns L * 26 candidates, each an O(L) string build. O(n * L) space for the set, queue, and visited words.

Done reading? Mark it so it sticks in your dashboard.

Next in CodingMax Area of Island