• [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;
        }
    }
  • 相关阅读:
    李宏毅2021春机器学习课程笔记——通过训练集上的Loss可获得的信息
    python学习-NotImplementedError的使用
    代码运行优化
    django实现上传文件读取文件内容
    django-admin上传下载文件
    AtCoder Beginner Contest 191 F
    敏感词过滤 AC自动机
    面经知识点
    select poll epoll实例
    socket用法
  • 原文地址:https://www.cnblogs.com/xuanlu/p/11711305.html
Copyright © 2020-2023  润新知