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 transformed word must exist in the word list. Note that beginWord is not a transformed word.
Note:
- Return an empty list if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
Example 1:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Example 2:
Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: [] Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
class Solution { public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { List<String> path = new ArrayList<>(); List<List<String>> result = new ArrayList<List<String>>(); HashMap<String, List<String>> graph = new HashMap<String, List<String>>(); HashSet<String> dict = new HashSet<>(wordList); buildGraph(beginWord, endWord, graph, dict); dfs(beginWord, endWord, graph, path, result); return result; } private void buildGraph(String beginWord, String endWord, HashMap<String, List<String>> graph, HashSet<String> dict) { HashSet<String> visited = new HashSet<>();//上一层visited过的 HashSet<String> toVisit = new HashSet<>();//这一层visited过的,因为同一层的选择权是相同的,即这一层可以选当前剩下的所有的string,到下一层就不可以了 Queue<String> queue = new LinkedList<>(); queue.offer(beginWord); toVisit.add(beginWord); boolean foundEnd = false; while(!queue.isEmpty()) { visited.addAll(toVisit);//把上一层visited过的加到visited里面 toVisit.clear();//把这层visited清空 int count = queue.size(); for (int i = 0; i < count; i++) { String word = queue.poll(); List<String> children = getNextLevel(word, dict); for (String child : children) { if (child.equals(endWord)) foundEnd = true; if (!visited.contains(child)) { if (!graph.containsKey(word)) { graph.put(word, new ArrayList<String>()); } graph.get(word).add(child); } if (!visited.contains(child) && !toVisit.contains(child)) { queue.offer(child); toVisit.add(child); } } } if (foundEnd) break;//意味着所有shortest path构成的graph已经build完成 } } private List<String> getNextLevel(String word, HashSet<String> dict) { List<String> result = new ArrayList<>(); char[] chs = word.toCharArray(); for (int i = 0; i < chs.length; i++) { for (char c = 'a'; c <= 'z'; c++) { if (chs[i] == c) continue; char t = chs[i]; chs[i] = c; String target = new String(chs); if (dict.contains(target)) result.add(target); chs[i] = t; } } return result; } private void dfs(String curWord, String endWord, HashMap<String, List<String>> graph, List<String> path, List<List<String>> result) { path.add(curWord); if (curWord.equals(endWord)) result.add(new ArrayList<String>(path)); else if (graph.containsKey(curWord)) { for (String nextWord : graph.get(curWord)) { dfs(nextWord, endWord, graph, path, result); path.remove(path.size()-1); } } } }
用bfs找到最短路径的长度,把最短路径们存成一个graph,然后dfs生成所有路径
和wordladder差不多