1 题目
1 Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that: 2 3 Only one letter can be changed at a time 4 Each intermediate word must exist in the dictionary 5 For example, 6 7 Given: 8 start = "hit" 9 end = "cog" 10 dict = ["hot","dot","dog","lot","log"] 11 As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", 12 return its length 5. 13 14 Note: 15 Return 0 if there is no such transformation sequence. 16 All words have the same length. 17 All words contain only lowercase alphabetic characters.
2 解法
a 单源最短路径
根据单词的距离是否为1,建立任意两个单词的联系。然后求图的单源最短路径。
b 遍历
方法a在节点比较多时,会挂掉。
该题题目是Word Ladder,暗含单词长度有限的条件,所以可以用25个字母逐一替换单词的某个位置,观察生成的新的单词是否存在于dict中。
实际上题目给出的字典列表为Map(而不是List),也暗示了这一点。
由于判断word是否存在于dict的效率是非常高的。该方法可以得到不超时的解:
1 package leetcode; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class WordLadder { 7 8 /** 9 * Given two words (start and end), and a dictionary, find the length of 10 * shortest transformation sequence from start to end, such that: 11 * 12 * Only one letter can be changed at a time Each intermediate word must 13 * exist in the dictionary 14 * 15 * For example, 16 * 17 * Given: start = "hit" end = "cog" dict = ["hot","dot","dog","lot","log"] 18 * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> 19 * "cog", return its length 5. 20 * 21 * Note: Return 0 if there is no such transformation sequence. All words 22 * have the same length. All words contain only lowercase alphabetic 23 * characters. 24 */ 25 26 protected boolean oneDiff(String word, String s) { 27 if (word.length() != s.length() || word.equals(s)) { 28 return false; 29 } 30 int flag = 0; 31 for (int i = 0; i < s.length(); i++) { 32 if (s.charAt(i) != word.charAt(i)) { 33 flag++; 34 } 35 if (flag > 1) { 36 return false; 37 } 38 } 39 return true; 40 } 41 42 public void extractOneDiffWords(Set<String> dict, Set<String> visited, 43 String word) { 44 StringBuffer sb; 45 for (int i = 0; i < word.length(); i++) { 46 for (char c = 'a'; c <= 'z'; c++) { 47 sb = new StringBuffer(word); 48 sb.setCharAt(i, c); 49 if (dict.contains(sb.toString())) { 50 visited.add(sb.toString()); 51 dict.remove(sb.toString()); 52 } 53 } 54 } 55 } 56 57 public int ladderLength(String start, String end, Set<String> dict) { 58 int minLen = 0; 59 if (start.equals(end) || oneDiff(start, end)) { 60 return minLen+2; 61 } 62 dict.add(end); 63 Set<String> visited = new HashSet<String>(); 64 Set<String> visitedTmp = null; 65 extractOneDiffWords(dict, visited, start); 66 while (!visited.isEmpty() && !dict.isEmpty()) { 67 minLen++; 68 visitedTmp = visited; 69 visited = new HashSet<String>(); 70 for (String word : visitedTmp) { 71 extractOneDiffWords(dict, visited, word); 72 } 73 if (visited.contains(end)) { 74 return minLen + 2; 75 } 76 } 77 return 0; 78 } 79 }