2
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {3
Set<String> dict = new HashSet(wordList);4
if (!dict.contains(endWord)) return new ArrayList();6
// adjacent words for each word7
Map<String, List<String>> adjacency = new HashMap();8
Queue<String> queue = new LinkedList();10
boolean found = false;12
// BFS for shortest path, keep removing visited words13
queue.offer(beginWord);14
dict.remove(beginWord);16
while (!found && !queue.isEmpty()) {17
int size = queue.size();18
// adjacent words in current level19
HashSet<String> explored = new HashSet();22
String word = queue.poll();24
if (adjacency.containsKey(word)) continue;26
// remove current word from dict, and search for adjacent words28
List<String> adjacents = getAdjacents(word, dict);29
adjacency.put(word, adjacents);31
for (String adj : adjacents) {32
if (!found && adj.equals(endWord)) found = true;38
// remove words explored in current level from dict39
for (String word : explored) dict.remove(word);42
// if a path exist, dfs to find all the paths43
if (found) return dfs(beginWord, endWord, adjacency, new HashMap());44
else return new ArrayList();47
private List<String> getAdjacents(String word, Set<String> dict) {48
List<String> adjs = new ArrayList();49
char[] wordChars = word.toCharArray();51
for (int i = 0; i < wordChars.length; i++)52
for (char c = 'a'; c <= 'z'; c++) {53
char temp = wordChars[i];56
String newAdj = new String(wordChars);57
if (dict.contains(newAdj)) adjs.add(newAdj);64
private List<List<String>> dfs(67
Map<String, List<String>> adjacency,68
Map<String, List<List<String>>> memo) {69
if (memo.containsKey(src)) return memo.get(src);71
List<List<String>> paths = new ArrayList();73
// reached dest? return list with dest word74
if (src.equals(dest)) {84
// no adjacent for curr word? return empty list85
List<String> adjacents = adjacency.get(src);86
if (adjacents == null || adjacents.isEmpty()) return paths;88
for (String adj : adjacents) {89
List<List<String>> adjPaths = dfs(adj, dest, adjacency, memo);91
for (List<String> path : adjPaths) {92
if (path.isEmpty()) continue;94
List<String> newPath =100
newPath.addAll(path);105
memo.put(src, paths);