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:
Every adjacent pair of words differs by a single letter.
Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.
sk == endWord
Given two words, beginWord and endWord, and a dictionary wordList, return the number of words in the shortest transformation sequence from beginWord to endWord, or 0 if no such sequence exists.
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
BFS, start with endWord
, every time change one character to decide if we want to add this to the queue.
Time complexity: o ( n ∗ n ∗ w o r d . l e n + n ) o(n*n*word.len + n) o(n∗n∗word.len+n), where n
is the length of wordList
, word.len
is the length of each word in wordList
Space complexity: o ( n ) o(n) o(n)
Code
python3
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
queue = collections.deque([(endWord, 1)])
visited = set()
wordList = set(wordList)
if endWord not in wordList:
return 0
while queue:
cur_word, step = queue.popleft()
if cur_word in visited:
continue
visited.add(cur_word)
if cur_word == beginWord:
return step
for i in range(len(cur_word)):
for new_char in 'abcdefghijklmnopqrstuvwxyz':
if new_char == cur_word[i]:
continue
new_word = f'{cur_word[:i]}{new_char}{cur_word[i+1:]}'
if new_word in wordList or new_word == beginWord:
queue.append((new_word, step + 1))
return 0