Problem Word Ladder II
Problem Description:
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) 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"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
Solution:
1 public List<List<String>> findLadders(String start, String end, Set<String> dict) { 2 List<List<String>> ret = new LinkedList<List<String>>(); 3 Map<String, List<String>> adjMap = new HashMap<String, List<String>>(); 4 5 List<Set<String>> layers = new LinkedList<Set<String>>(); 6 layers.add(0, new HashSet<String>()); 7 layers.add(1, new HashSet<String>()); 8 dict.add(start); 9 dict.add(end); 10 int cur = 0; 11 int pre = 1; 12 13 layers.get(cur).add(start); 14 // BFS 15 while (! layers.get(cur).isEmpty() && ! layers.get(cur).contains(end)) { 16 cur = (cur == 0) ? 1 : 0; 17 pre = (pre == 0) ? 1 : 0; 18 for (String word : layers.get(pre)) dict.remove(word); 19 20 layers.get(cur).clear(); 21 for (String word: layers.get(pre)) { 22 for (int i = 0; i < word.length(); ++i) { 23 char[] charArray = word.toCharArray(); 24 for (char c = 'a'; c <= 'z'; ++c) { 25 if (charArray[i] == c) continue; 26 charArray[i] = c; 27 String temp = new String(charArray); 28 if (dict.contains(temp)) { 29 if (! adjMap.containsKey(temp)) { 30 List<String> path = new LinkedList<String>(); 31 adjMap.put(temp, path); 32 } 33 adjMap.get(temp).add(word); 34 layers.get(cur).add(temp); 35 } 36 } 37 } 38 } 39 40 } 41 42 if (layers.get(cur).isEmpty()) { 43 return ret; 44 } 45 46 List<String> path = new LinkedList<String> (); 47 buildPath(ret, adjMap, path, end, start); 48 return ret; 49 } 50 public void buildPath(List<List<String>> ret, Map<String, List<String>> adjMap, List<String> path, String cur, String start) { 51 if (start.equals(cur)) { 52 path.add(0, cur); 53 ret.add(path); 54 return; 55 } 56 57 path.add(0, cur); 58 for (int i = 0; i < adjMap.get(cur).size(); ++i) { 59 List<String> copy = new LinkedList(path); 60 buildPath(ret, adjMap, copy, adjMap.get(cur).get(i), start); 61 } 62 }