1
# Runtime: 80 ms (Top 72.71%) | Memory: 14.5 MB (Top 54.17%)7
self, beginWord: str, endWord: str, wordList: List[str]10
Given a wordlist, we perform BFS traversal to generate a word tree where11
every node points to its parent node.13
Then we perform a DFS traversal on this tree starting at the endWord.15
if endWord not in wordList:16
# end word is unreachable19
# first generate a word tree from the wordlist20
word_tree = self.getWordTree(beginWord, endWord, wordList)22
# then generate a word ladder from the word tree23
return self.getLadders(beginWord, endWord, word_tree)26
self, beginWord: str, endWord: str, wordList: List[str]27
) -> Dict[str, List[str]]:29
BFS traversal from begin word until end word is encountered.31
This functions constructs a tree in reverse, starting at the endWord.33
# Build an adjacency list using patterns as keys34
# For example: ".it" -> ("hit"), "h.t" -> ("hit"), "hi." -> ("hit")35
adjacency_list = defaultdict(list)37
for i in range(len(word)):38
pattern = word[:i] + Solution.WILDCARD + word[i + 1 :]39
adjacency_list[pattern].append(word)41
# Holds the tree of words in reverse order42
# The key is an encountered word.43
# The value is a list of preceding words.44
# For example, we got to beginWord from no other nodes.45
# {a: [b,c]} means we got to "a" from "b" and "c"46
visited_tree = {beginWord: []}48
# start off the traversal without finding the word51
q = deque([beginWord])52
while q and not found:55
# keep track of words visited at this level of BFS56
visited_this_level = {}61
for i in range(len(word)):62
# for each pattern of the current word63
pattern = word[:i] + Solution.WILDCARD + word[i + 1 :]65
for next_word in adjacency_list[pattern]:66
if next_word == endWord:67
# we don't return immediately because other68
# sequences might reach the endWord in the same71
if next_word not in visited_tree:72
if next_word not in visited_this_level:73
visited_this_level[next_word] = [word]74
# queue up next word iff we haven't visited it yet75
# or already are planning to visit it78
visited_this_level[next_word].append(word)80
# add all seen words at this level to the global visited tree81
visited_tree.update(visited_this_level)86
self, beginWord: str, endWord: str, wordTree: Dict[str, List[str]]89
DFS traversal from endWord to beginWord in a given tree.92
def dfs(node: str) -> List[List[str]]:95
if node not in wordTree:99
parents = wordTree[node]100
for parent in parents: