```Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]```

Leetcode 里面通过概率最低的一道题，参看了别人的解法：利用bfs 层序遍历 如果队列中有end 那么结束遍历（到最短的一层就结束）

```  1 import java.util.ArrayList;
2 import java.util.HashMap;
3 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Queue;
8 import java.util.Set;
9
10 public class Solution {
11     class WordWithLevel {
12         String word;
13         int level;
14
15         public WordWithLevel(String word, int level) {
16             this.word = word;
17             this.level = level;
18         }
19     }
20
21     private String end;
22     private ArrayList<ArrayList<String>> result;
23     private Map<String, List<String>> nextMap;
24
25     public ArrayList<ArrayList<String>> findLadders(String start, String end,
26             HashSet<String> dict) {
27         result = new ArrayList<ArrayList<String>>();
28         this.end = end;
29
30         // unvisited words set
31         Set<String> unVisited = new HashSet<String>();
34         unVisited.remove(end);
35
36         // used to record the map info of <word : the words of next level>
37         nextMap = new HashMap<String, List<String>>();
38         for (String e : unVisited) {
39             nextMap.put(e, new ArrayList<String>());
40         }
41
42         // BFS to search from the end to start
43         Queue<WordWithLevel> queue = new LinkedList<WordWithLevel>();
44         queue.add(new WordWithLevel(end, 0));
45         boolean found = false;
46         int finalLevel = Integer.MAX_VALUE;
47         int currentLevel = 0;
48         int preLevel = 0;
49         Set<String> visitedWordsInThisLevel = new HashSet<String>();
50         while (!queue.isEmpty()) {
51             WordWithLevel wordWithLevel = queue.poll();
52             String word = wordWithLevel.word;
53             currentLevel = wordWithLevel.level;
54             if (found && currentLevel > finalLevel) {
55                 break;
56             }
57             if (currentLevel > preLevel) {
58                 unVisited.removeAll(visitedWordsInThisLevel);
59             }
60             preLevel = currentLevel;
61             char[] wordCharArray = word.toCharArray();
62             for (int i = 0; i < word.length(); ++i) {
63                 char originalChar = wordCharArray[i];
64                 boolean foundInThisCycle = false;
65                 for (char c = 'a'; c <= 'z'; ++c) {
66                     wordCharArray[i] = c;
67                     String newWord = new String(wordCharArray);
68                     if (c != originalChar && unVisited.contains(newWord)) {
70                         if (newWord.equals(start)) {
71                             found = true;
72                             finalLevel = currentLevel;
73                             foundInThisCycle = true;
74                             break;
75                         }
76                         if (visitedWordsInThisLevel.add(newWord)) {
78                                     currentLevel + 1));
79                         }
80                     }
81                 }
82                 if (foundInThisCycle) {
83                     break;
84                 }
85                 wordCharArray[i] = originalChar;
86             }
87         }
88
89         if (found) {
90             // dfs to get the paths
91             ArrayList<String> list = new ArrayList<String>();
93             getPaths(start, list, finalLevel + 1);
94         }
95         return result;
96     }
97
98     private void getPaths(String currentWord, ArrayList<String> list, int level) {
99         if (currentWord.equals(end)) {
101         } else if (level > 0) {
102             List<String> parentsSet = nextMap.get(currentWord);
103             for (String parent : parentsSet) {
105                 getPaths(parent, list, level - 1);
106                 list.remove(list.size() - 1);
107             }
108         }
109     }
110 }```

``` 1 public class Solution {
2     public ArrayList<ArrayList<String>> findLadders(String start, String end, Set<String> dict) {
3         ArrayList<String> Ladder=new ArrayList<String>();
4         ArrayList<ArrayList<String>> LadderList=new ArrayList<ArrayList<String>>();
5         if(start.length() != end.length()) return LadderList;
8     }
9
10     public void shortestladders(String start, String end, Set<String> dict, ArrayList<String> Ladder, ArrayList<ArrayList<String>> LadderList){
12         if(within(start, end)) { //end is only 1 bit different from start
14             if(LadderList.isEmpty()) { //LadderList is empty, so Ladder is definately shortest
16             }
17             else { //LadderList is not empty, so need comparition
18                 ArrayList<String> shortestLadder = LadderList.get(0); // select one from LadderList
22                 }
25                 }
26                 // new found Ladder is longer than elems in LadderList, so do not change LadderList
27             }
29         }
30
31         else { //end is more than 1 bit different from start, so look for temp elems in dict which is 1 bit different from start
32             if(!dict.isEmpty()) {
33                 for(String temp:dict){
34                     if(within(start, temp)){
35                         dict.remove(start);
38                     }
39                 }
40             }
41
42         }
44     }
45
46     public boolean within(String first, String second){
47         int diff=0;
48         for(int k=0; k<first.length(); k++){
49             if(first.charAt(k)!=second.charAt(k)){
50                 diff++;
51             }
52         }
53         if(diff==1) return true;
54         else return false;
55     }
56 }```