[LC] 127. Word Ladder

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output: 5

Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: 0

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

Solution 1:
Time: O(N^2) lead to TLE
Space: O(N)
 1 class Solution:
 2     def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
 3         if beginWord == endWord or endWord not in wordList:
 4             return 0
 5         step = 1
 6         ladder_dict = self.build_dict(beginWord, wordList)
 7         from collections import deque
 8         queue = deque([beginWord])
 9         visited = {beginWord}
10         while queue:
11             size = len(queue)
12             for i in range(size):
13                 cur_word = queue.popleft()
14                 if cur_word == endWord:
15                     return step 
16                 word_lst = ladder_dict.get(cur_word)
17                 for word in word_lst:
18                     if word not in visited:
19                         queue.append(word)
20                         visited.add(word)
21             step += 1
22         return 0
23     
24     def build_dict(self, beginWord, wordList):
25         my_dict = {}
26         for w_i in wordList:
27             my_dict[w_i] = []
28             for w_j in wordList:
29                 if self.diff(w_i, w_j) == 1:
30                     my_dict[w_i].append(w_j)
31         if beginWord not in my_dict:
32             my_dict[beginWord] = []
33             for w_j in wordList:
34                 if self.diff(beginWord, w_j) == 1:
35                     my_dict[beginWord].append(w_j)
36         return my_dict
37     
38     def diff(self, s, t):
39         count = 0
40         for i in range(len(s)):
41             if s[i] != t[i]:
42                 count += 1
43         return count
44                     

 

Solution 2:

Time: O (N * 26 ^ | Wordlen |)

Space: O(N)

 1 class Solution(object):
 2     def ladderLength(self, beginWord, endWord, wordList):
 3         """
 4         :type beginWord: str
 5         :type endWord: str
 6         :type wordList: List[str]
 7         :rtype: int
 8         """
 9         if endWord not in wordList:
10             return 0
11         import string
12         from collections import deque
13         alpha = string.ascii_lowercase
14         queue = deque([beginWord])
15         visited = {beginWord}
16         word_list = set(wordList)
17         step = 1
18 
19         while queue:
20             size = len(queue)
21             for i in range(size):
22                 cur_word = queue.popleft()
23                 if cur_word == endWord:
24                     return step 
25                 
26                 for i in range(len(cur_word)):
27                     for char in alpha:
28                         new_word = cur_word[:i] + char + cur_word[i+1: ]
29                         if new_word in word_list and new_word not in visited:
30                             queue.append(new_word)
31                             visited.add(new_word)
32             step += 1
33         return 0
34         

 

Guess you like

Origin www.cnblogs.com/xuanlu/p/11711305.html