Given two words, beginWord
and endWord
, and a dictionary wordList
, determine the shortest transformation sequence from beginWord
to endWord
. The transformation must adhere to these rules:
wordList
(except for the beginWord
).Return the number of words in the shortest transformation sequence, or 0 if no such sequence exists.
For example:
beginWord
= "hit", endWord
= "cog", wordList
=
["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> "cog", which is 5 words long.
beginWord
= "hit", endWord
= "cog", wordList
=
["hot","dot","dog","lot","log"]
Output: 0
Explanation: The endWord
"cog" is not in wordList
, therefore there is no valid transformation sequence.
Write a function to efficiently solve this problem.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to the Word Ladder problem is like trying every single possible path between the start and end word. We explore all possible word sequences, checking if each word differs by only one letter from the previous word. We continue until we either find the end word or have exhausted all possibilities.
Here's how the algorithm would work step-by-step:
def word_ladder_brute_force(begin_word, end_word, word_list):
word_set = set(word_list)
if end_word not in word_set:
return 0
queue = [(begin_word, 1)]
visited = {begin_word}
while queue:
current_word, current_length = queue.pop(0)
if current_word == end_word:
return current_length
# Iterate through all possible next words
for next_word in word_list:
if next_word not in word_set:
continue
if next_word in visited:
continue
difference_count = 0
for i in range(len(current_word)):
if current_word[i] != next_word[i]:
difference_count += 1
# Only proceed if words are 1 character different
if difference_count == 1:
queue.append((next_word, current_length + 1))
visited.add(next_word)
return 0
The problem is to find the shortest sequence of words that transforms one word into another, changing only one letter at a time. We'll use a method that explores all possible paths simultaneously, branching out from the starting word until we find the target word, ensuring the shortest route is found first.
Here's how the algorithm would work step-by-step:
from collections import deque
def word_ladder(begin_word, end_word, word_list):
word_set = set(word_list)
if end_word not in word_set:
return 0
queue = deque([(begin_word, 1)])
visited = {begin_word}
while queue:
current_word, path_length = queue.popleft()
if current_word == end_word:
return path_length
# Iterate through all possible one-letter variations
for i in range(len(current_word)):
for char_code in range(ord('a'), ord('z') + 1):
new_char = chr(char_code)
new_word = current_word[:i] + new_char + current_word[i+1:]
# Check for valid words that can be enqueued
if new_word in word_set and new_word not in visited:
# Prevent cycles by tracking visited words
visited.add(new_word)
queue.append((new_word, path_length + 1))
return 0
Case | How to Handle |
---|---|
startWord or endWord is null or empty | Return 0 immediately as no valid transformation is possible. |
dictionary is null or empty | If endWord equals startWord, return 1, otherwise return 0 as no transformation is possible. |
startWord and endWord are the same | Return 1 if startWord equals endWord as no transformation is needed. |
endWord is not present in the dictionary | Return 0 as a transformation to a non-existent word is impossible. |
dictionary contains words of different lengths | The one-letter-difference check will effectively ignore words of differing length; continue search with valid length words only. |
No transformation sequence exists between startWord and endWord | BFS search will exhaust all possibilities and return 0 when the queue is empty and the endWord hasn't been reached. |
Dictionary contains duplicate words | Treat duplicates as a single entry as they offer no benefit to the shortest path. |
Large dictionary size could lead to memory or time complexity issues with BFS. | Ensure algorithm uses efficient data structures and early exit conditions to minimize the search space. |