[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         

 

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;
    }
}
posted @ 2019-10-21 05:16  xuan_abc  阅读(318)  评论(0)    收藏  举报