class Solution { public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { List<List<String>> res=new ArrayList<List<String>>(); Set<String> dict=new HashSet<String>(wordList); if(!dict.contains(endWord)) return res; Set<String> set1=new HashSet<String>(Arrays.asList(beginWord)); Set<String> set2=new HashSet<String>(Arrays.asList(endWord)); Map<String, List<String>> map=new HashMap<String, List<String>>(); buildmap(set1,set2,dict,map,false); generatePath(new ArrayList<String>(Arrays.asList(beginWord)),res,map,endWord); return res; } private void buildmap(Set<String> set1, Set<String> set2, Set<String> dict, Map<String, List<String>> map, boolean flip){ if(set1.isEmpty()) return; if(set1.size()>set2.size()) { buildmap(set2, set1, dict, map, !flip); return; } dict.removeAll(set1); Set<String> set3=new HashSet<String>(); boolean found=false; for(String w:set1) { for(int i=0;i<w.length();i++) { char[] arr=w.toCharArray(); for(char ch='a';ch<='z';ch++) { arr[i]=ch; String nw=new String(arr); String key=flip?nw:w; String val=flip?w:nw; if(!map.containsKey(key)) map.put(key, new ArrayList<String>()); if(set2.contains(nw)) { found=true; map.get(key).add(val); } if(found==false&&dict.contains(nw)) { map.get(key).add(val); set3.add(nw); } } } } if(found==false) buildmap(set2,set3,dict,map,!flip); } private void generatePath(List<String> path, List<List<String>> res, Map<String, List<String>> map, String endWord){ String word=path.get(path.size()-1); if(word.equals(endWord)) { if(res.size()>0&&path.size()<res.get(0).size()) res.clear(); if(res.size()==0||path.size()==res.get(0).size()) res.add(new ArrayList<String>(path)); return; } if(!map.containsKey(word)) return; for(String w:map.get(word)) { if(path.contains(w)) continue; path.add(w); generatePath(path,res,map,endWord); path.remove(path.size()-1); } } }