--- title: '127. Word Ladder' description: 'A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:' icon: dot topics: - { name: "Hash Table", slug: "hash-table" } - { name: "String", slug: "string" } - { name: "Breadth-First Search", slug: "breadth-first-search" } - { name: "Bidirectional Search", slug: "bidirectional-search" } issue: "https://github.com/prdlk/leetcode/issues/138" sidebar: label: 'Word Ladder' badge: 'Hard' --- ### Example 1: - Input: `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. ### Example 2: - Input: `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. ### Constraints: - `1 <= beginWord.length <= 10` - `endWord.length == beginWord.length` - `1 <= wordList.length <= 5000` - `wordList[i].length == beginWord.length` - `beginWord`, `endWord`, and `wordList[i]` consist of lowercase English letters. - `beginWord != endWord` - All the words in `wordList` are unique. ## Solution ```py import collections class Solution: def ladderLength(self, beginWord: str, endWord: str, wordList: list[str]) -> int: if endWord not in wordList: return 0 adj = collections.defaultdict(list) wordList.append(beginWord) for word in wordList: for j in range(len(word)): pattern = word[:j] + "*" + word[j + 1 :] adj[pattern].append(word) visit = set([beginWord]) q = collections.deque([beginWord]) res = 1 while q: for i in range(len(q)): word = q.popleft() if word == endWord: return res for j in range(len(word)): pattern = word[:j] + "*" + word[j + 1 :] for adjWord in adj[pattern]: if adjWord not in visit: visit.add(adjWord) q.append(adjWord) res += 1 return 0 ```