Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["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.
bug code
1 public class Solution { 2 public int ladderLength(String start, String end, HashSet<String> dict) { 3 // Start typing your Java solution below 4 // DO NOT write main() function 5 if(dict.size() == 0 || start.equals(end)){ 6 return 0; 7 } 8 //dict.add(start); 9 dict.remove(start); 10 dict.add(end); 11 int result = getLen(start, end, dict, 0); 12 if(result == 0){ 13 return result; 14 } 15 return result + 1; 16 } 17 18 public int getLen(String start, String end, HashSet<String> dict, int len){ 19 if(start.equals(end)){ 20 return len; 21 } 22 23 HashSet<String> neighbors = getNeighbors(start, dict); 24 int maxLen = len; 25 for(String n : neighbors){ 26 dict.remove(n); 27 int tmp = getLen(n, end, dict, len + 1); 28 if(tmp > maxLen){ 29 maxLen = tmp; 30 } 31 dict.add(n); 32 } 33 return maxLen; 34 } 35 36 public HashSet<String> getNeighbors(String start, HashSet<String> dict){ 37 HashSet<String> result = new HashSet<String>(); 38 for(int i = 0; i < start.length(); i++){ 39 StringBuffer sb = new StringBuffer(); 40 if(i == 1){ 41 sb.append(start.substring(0, 1)); 42 } else if(i == 0){ 43 44 } else { 45 sb.append(start.substring(0, i)); 46 } 47 for(char c = 'a'; c <= 'z'; c++){ 48 if(c != start.charAt(i)){ 49 sb.append(c).append(start.substring(i + 1)); 50 if(dict.contains(sb.toString())){ 51 result.add(sb.toString()); 52 } 53 } 54 } 55 } 56 return result; 57 } 58 }
BFS
类似于图的遍历,将start一步内可以到达的单词加入到queue中,并将相应长度放入queue中
每次从queue中poll出一个单词,看是否是目标单词,如果是则返回相应长度
对每个单词的每一位进行变化('a'-'z'), 看是否在dict中,如在则说明该单词是转换路径中的一个
由于在找到一个转换路径后就返回,此返回值可以确保是最小值
1 public class Solution { 2 public static int ladderLength(String start, String end, 3 HashSet<String> dict) { 4 int result = 0; 5 if (dict.size() == 0) { 6 return result; 7 } 8 9 dict.add(start); 10 dict.add(end); 11 12 result = BFS(start, end, dict); 13 14 return result; 15 } 16 17 private static int BFS(String start, String end, HashSet<String> dict) { 18 Queue<String> queue = new LinkedList<String>(); 19 Queue<Integer> length = new LinkedList<Integer>(); 20 queue.add(start); 21 length.add(1); 22 23 while (!queue.isEmpty()) { 24 String word = queue.poll(); 25 int len = length.poll(); 26 27 if (match(word, end)) { 28 return len; 29 } 30 31 for (int i = 0; i < word.length(); i++) { 32 char[] arr = word.toCharArray(); 33 for (char c = 'a'; c <= 'z'; c++) { 34 if (c == arr[i]) 35 continue; 36 37 arr[i] = c; 38 String str = String.valueOf(arr); 39 if (dict.contains(str)) { 40 queue.add(str); 41 length.add(len + 1); 42 dict.remove(str); 43 } 44 } 45 } 46 } 47 48 return 0; 49 } 50 51 private static boolean match(String word, String end) { 52 if (word.equals(end)) { 53 return true; 54 } 55 return false; 56 } 57 }