Word Ladder II
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.
Hash + Queue
1 public class Solution { 2 public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) { 3 List<List<String>> ladders = new ArrayList<>(); 4 Map<String,List<String>> map = new HashMap<>(); 5 Map<String, Integer> distance = new HashMap<>(); 6 7 wordList.add(beginWord); 8 wordList.add(endWord); 9 10 bfs(map, distance, beginWord, endWord, wordList); 11 List<String> path = new ArrayList<>(); 12 dfs(ladders, path, endWord, beginWord, map, distance); 13 return ladders; 14 } 15 private void bfs(Map<String, List<String>> map, Map<String, Integer> distance, String start, 16 String end, Set<String> dict) { 17 Queue<String> q = new LinkedList<>(); 18 q.offer(start); 19 distance.put(start, 0); 20 for (String s : dict) { 21 map.put(s, new ArrayList<String>()); 22 } 23 while (!q.isEmpty()) { 24 String crt = q.poll(); 25 List<String> nextList = expand(crt, dict); 26 for (String next : nextList) { 27 map.get(next).add(crt); 28 if (!distance.containsKey(next)) { 29 distance.put(next, distance.get(crt) + 1); 30 q.offer(next); 31 } 32 } 33 } 34 } 35 36 private List<String> expand(String crt, Set<String> dict) { 37 List<String> expansion = new ArrayList<String>(); 38 for (int i = 0; i < crt.length(); i++) { 39 for (char ch = 'a'; ch <= 'z'; ch++) { 40 if (ch != crt.charAt(i)) { 41 String expanded = crt.substring(0, i) + ch + crt.substring(i + 1); 42 if (dict.contains(expanded)) { 43 expansion.add(expanded); 44 } 45 } 46 } 47 } 48 return expansion; 49 } 50 51 private void dfs(List<List<String>> ladders, List<String> path, String crt, 52 String start, Map<String, List<String>> map, 53 Map<String, Integer> distance) { 54 path.add(crt); 55 if (crt.equals(start)) { 56 Collections.reverse(path); 57 ladders.add(new ArrayList<String>(path)); 58 Collections.reverse(path); 59 } else { 60 for (String next : map.get(crt)) { 61 if (distance.get(crt) == distance.get(next) + 1) { 62 dfs(ladders, path, next, start, map, distance); 63 } 64 } 65 } 66 path.remove(path.size() - 1); 67 } 68 }