public static List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
HashMap<String, List<String>> neighbors = new HashMap<String, List<String>>();
HashMap<String, Integer> ladder = new HashMap<String, Integer>();
bfs(beginWord, endWord, wordList, neighbors, ladder);
List<String> path=new ArrayList<String>();
List<List<String>> res= new ArrayList<List<String>>();
dfs(neighbors, ladder, path, res, endWord, beginWord);
return res;
}
private static void dfs( HashMap<String, List<String>> neighbors, HashMap<String, Integer> ladder, List<String> path, List<List<String>> res, String end, String start){
path.add(end);
if(end.equals(start)){
Collections.reverse(path);
res.add(new ArrayList<String>(path));
Collections.reverse(path);
path.remove(path.size()-1);
return;
}
List<String> parents = neighbors.get(end);
for(String s : parents){
if(ladder.get(s) == (ladder.get(end)-1)){
dfs(neighbors, ladder, path, res, s, start);
}
}
path.remove(path.size()-1);
}
private static void bfs(String begin, String end, Set<String> wordlist, HashMap<String, List<String>> neighbors, HashMap<String, Integer> ladder){
wordlist.add(begin); wordlist.add(end);
LinkedList<String> q = new LinkedList<String>();
q.offer(begin);
ladder.put(begin, 0);
for(String s : wordlist){
neighbors.put(s, new ArrayList<String>());
}
while(!q.isEmpty()){
String cur=q.poll();
ArrayList<String> nextlayer = findnext(cur, wordlist);
for(String next : nextlayer){
neighbors.get(cur).add(next);
if(!ladder.containsKey(next)){
ladder.put(next, ladder.get(cur) + 1);
q.offer(next);
}
}
}
}
private static ArrayList<String> findnext(String cur, Set<String> wordlist){
ArrayList<String> nextlayer = new ArrayList<String>();
for(int i=0;i<cur.length();i++){
for(char c='a'; c<='z'; c++){
if(!(cur.charAt(i)==c)){
String next=cur.substring(0,i) + c + cur.substring(i+1);
if(wordlist.contains(next)) nextlayer.add(next);
}
}
}
return nextlayer;
}