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:
- Only one letter can be changed at a time.
- 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
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { int res = 0, len = 1; Set<String> dict = new HashSet<>(wordList); Queue<String> queue = new LinkedList<>(); Set<String> visited = new HashSet<>(); queue.offer(beginWord); visited.add(beginWord); while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { String cur = queue.poll(); for(String next : getNextWord(cur, dict)) { if (visited.contains(next)) { continue; } if (next.equals(endWord)) { return len + 1; } queue.offer(next); visited.add(next); } } len += 1; } return 0; } private List<String> getNextWord(String cur, Set<String> dict) { List<String> list = new ArrayList<>(); for (int i = 0; i < cur.length(); i++) { char[] charArr = cur.toCharArray(); for (char j = 'a'; j <= 'z'; j++) { if (j == charArr[i]) { continue; } charArr[i] = j; String newString = new String(charArr); if (dict.contains(newString)) { list.add(newString); } } } return list; } }
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { Queue<String> queue = new LinkedList<>(); Set<String> set = new HashSet<String>(wordList); if (!set.contains(endWord)) { return 0; } int res = 0; set.add(endWord); queue.offer(beginWord); while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { String cur = queue.poll(); if (cur.equals(endWord)) { return res + 1; } for (int k = 0; k < cur.length(); k++) { // need to initialize inside of string loop char[] charArr = cur.toCharArray(); for (int j = 0; j < 26; j++) { char tmpChar = (char)('a' + j); if (tmpChar == charArr[k]) { continue; } charArr[k] = tmpChar; String tmpStr = new String(charArr); if (set.contains(tmpStr)) { set.remove(tmpStr); queue.offer(tmpStr); } } } } res += 1; } return 0; } }