A transformation sequence from word
beginWord
to wordendWord
using a dictionarywordList
is a sequence of wordsbeginWord -> s1 -> s2 -> ... -> sk
such that:
- Every adjacent pair of words differs by a single letter.
- Every
si
for1 <= i <= k
is inwordList
. Note thatbeginWord
does not need to be inwordList
.sk == endWord
Given two words,
beginWord
andendWord
, and a dictionarywordList
, return the number of words in the shortest transformation sequence frombeginWord
toendWord
, or0
if no such sequence exists.
from collections import defaultdict, deque
class Solution:
def ladderLength(self, beginWord, endWord, wordList):
if endWord not in wordList:
return 0
if beginWord not in wordList:
wordList.append(beginWord)
# record graph[pattern] = corresponding words
# E.g., '*ot': ['hot', 'dot', 'lot']
graph = defaultdict(list)
for word in wordList:
for i in range(len(word)):
pattern = word[:i] + '*' + word[i+1:]
graph[pattern].append(word)
# BFS - q: deque to pop current word; path: record words already seen
q = deque([beginWord])
path = set()
path.add(beginWord)
count = 1
while q:
for i in range(len(q)):
word = q.popleft()
if word == endWord:
return count
for j in range(len(word)):
pattern = word[:j] + '*' + word[j+1:]
# for each word following this pattern
for w in graph[pattern]:
if w not in path:
q.append(w)
path.add(w)
# path length += 1
count += 1
return 0