• Word Ladder 解答


    Question

    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 intermediate word must exist in the word list

    For example,

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

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

    Note:

      • Return 0 if there is no such transformation sequence.
      • All words have the same length.
      • All words contain only lowercase alphabetic characters.

    Solution 1 -- BFS

     1 class WordNode{
     2     String word;
     3     int numSteps;
     4     
     5     public WordNode(String word, int numSteps){
     6         this.word = word;
     7         this.numSteps = numSteps;
     8     }
     9 }
    10 
    11 public class Solution {
    12     public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
    13         Queue<WordNode> queue = new LinkedList<WordNode>();
    14         queue.add(new WordNode(beginWord, 1));
    15         
    16         wordList.add(endWord);
    17         
    18         // 由于这里纪录了每个词的最小步数,所以不用两个list
    19         while (queue.size() > 0) {
    20             WordNode topNode = queue.remove();
    21             String current = topNode.word;
    22             
    23             if (current.equals(endWord))
    24                 return topNode.numSteps;
    25             
    26             char[] arr = current.toCharArray();
    27             // 穷举法
    28             for (int i = 0; i < arr.length; i++) {
    29                 for (char c = 'a'; c <= 'z'; c++) {
    30                     char tmp = arr[i];
    31                     if (arr[i] != c)
    32                         arr[i] = c;
    33                     
    34                     String newWord = new String(arr);
    35                     if (wordList.contains(newWord)) {
    36                         queue.add(new WordNode(newWord, topNode.numSteps + 1));
    37                         wordList.remove(newWord);
    38                     }
    39                     arr[i] = tmp;
    40                 }
    41             }
    42         }
    43         return 0;
    44     }
    45 }

    Solution 2 -- BFS & Adjacency List

    Basic idea is: 1. construct adjacency list 2. BFS

    Constructing adjacency list uses O(n2) time, and BFS is O(n). Total time complexity is O(n2), when testing in leetcode, it reports "time limit exceeded".

     1 public class Solution {
     2     public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
     3         if (wordList == null)
     4             return -1;
     5         int step = 1;
     6         if (beginWord.equals(endWord))
     7             return 1;
     8         // Construct adjacency lists for words
     9         // Do not forget start word and end word
    10         wordList.add(beginWord);
    11         wordList.add(endWord);
    12         Map<String, List<String>> adjacencyList = new HashMap<String, List<String>>();
    13         Map<String, Boolean> visited = new HashMap<String, Boolean>();
    14         int length = wordList.size();
    15         String[] wordList2 = new String[length];
    16         int i = 0;
    17         for (String current : wordList) {
    18             wordList2[i] = current;
    19             i++;
    20         }
    21         // Initialization
    22         for (i = 0; i < length; i++) {
    23             adjacencyList.put(wordList2[i], new ArrayList<String>());
    24             visited.put(wordList2[i], false);
    25         }
    26         
    27         for (i = 0; i < length; i++) {
    28             String current = wordList2[i];
    29             // Construct adjacency list for each element
    30             for (int j = i + 1; j < length; j++) {
    31                 String next = wordList2[j];
    32                 if (isAdjacent(current, next)) {
    33                     List<String> list1 = adjacencyList.get(current);
    34                     list1.add(next);
    35                     adjacencyList.put(current, list1);
    36                     List<String> list2 = adjacencyList.get(next);
    37                     list2.add(current);
    38                     adjacencyList.put(next, list2);
    39                 }
    40             }
    41         }
    42         
    43         // BFS
    44         List<String> current = new ArrayList<String>();
    45         List<String> next;
    46         current.add(beginWord);
    47         visited.put(beginWord, true);
    48         while (current.size() > 0) {
    49             step++;
    50             next = new ArrayList<String>();
    51             for (String currentString : current) {
    52                 List<String> neighbors = adjacencyList.get(currentString);
    53                 if (neighbors == null)
    54                     continue;
    55                 for (String neighbor : neighbors) {
    56                     if (neighbor.equals(endWord))
    57                         return step;
    58                     if (!visited.get(neighbor)) {
    59                         next.add(neighbor);
    60                         visited.put(neighbor, true);
    61                     }
    62                 }
    63             }
    64             current = next;
    65         }
    66         return -1;
    67         
    68     }
    69     
    70     private boolean isAdjacent(String current, String next) {
    71         if (current.length() != next.length())
    72             return false;
    73         int length = current.length();
    74         int diff = 0;
    75         for (int i = 0; i < length; i++) {
    76             char a = current.charAt(i);
    77             char b = next.charAt(i);
    78             if (a != b)
    79                 diff++;
    80         }
    81         if (diff == 1)
    82             return true;
    83         return  false;
    84     }
    85 }

     Python version

     1 from collections import deque
     2 from collections import defaultdict
     3     
     4 class Solution:
     5     def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
     6         if endWord not in wordList:
     7             return 0
     8         queue = deque()
     9         queue.append((beginWord, 1))
    10         visited = set([beginWord])
    11         adjacency_map = defaultdict(list)
    12         L = len(beginWord)
    13         # Pre-process
    14         for word in wordList:
    15             for i in range(L):
    16                 adjacency_map[word[:i] + "*" + word[i+1:]].append(word)
    17         # BFS
    18         while queue:
    19             curr_word, curr_steps = queue.popleft()
    20             if curr_word == endWord:
    21                 return curr_steps
    22             # List all possibilities
    23             for i in range(L):
    24                 key = curr_word[:i] + "*" + curr_word[i+1:]
    25                 if key in adjacency_map:
    26                     neighbors = adjacency_map[key]
    27                     for neighbor in neighbors:
    28                         if neighbor == endWord:
    29                             return curr_steps + 1
    30                         if neighbor not in visited:
    31                             queue.append((neighbor, curr_steps + 1))
    32                             visited.add(neighbor)
    33                     adjacency_map[key] = {}
    34         return 0
  • 相关阅读:
    Less(27a)GET
    Less(27)GET
    虚拟机打开文件黑屏
    mysql开放远程连接权限
    fidder如何设置代理转发
    如何获取APK的包名
    ADB调试原理之通俗版本
    adb端口5037被占用怎么办
    ADB调试原理
    如何使用无线调试手机
  • 原文地址:https://www.cnblogs.com/ireneyanglan/p/4866088.html
Copyright © 2020-2023  润新知