Given two words (beginWordandendWord), and a dictionary's word list, find all shortest transformation sequence(s) frombeginWordtoendWord, such that:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
class Solution {
Map<String,List<String>> father = new HashMap<String,List<String>>();
Map<String, Integer> distance = new HashMap<String, Integer>();
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
List<List<String>> ret = new ArrayList<>();
if(!wordList.contains(endWord))
return ret;
List<String> path = new ArrayList<String>();
wordList.add(beginWord);
// wordList.add(endWord);
bfs(beginWord, endWord, wordList);
dfs(ret, path, endWord, beginWord);
return ret;
}
void dfs(List<List<String>> ret, List<String> path, String s, String e){
path.add(s);
if(s.equals(e)){
List<String> nl = new ArrayList<String>(path);
Collections.reverse(nl);
ret.add(nl);
}else{
for(String f : father.get(s)){
//distance来找到合适的father。
if(distance.containsKey(f) && distance.get(s) == distance.get(f) + 1){
dfs(ret, path, f, e);
}
}
}
path.remove(path.size() - 1);
}
List<String> getNextWord(String cur, Set
<String> wordList){
List<String> ret = new ArrayList<String>();
char[] cs = cur.toCharArray();
for(int i = 0; i < cur.length(); i ++){
for(char c = 'a' ; c <= 'z'; c ++){
if(cs[i] == c){
continue;
}
char temp = cs[i];
cs[i] = c;
String nw = new String(cs);
if(wordList.contains(nw)){
ret.add(nw);
}
cs[i] = temp;
}
}
return ret;
}
void bfs(String beginWord, String endWord, List<String> wordList){
Queue<String> q = new LinkedList<String>();
//用set存字典,为了让查contains更快
Set<String> dict = new HashSet<>();
for (String word : wordList) {
father.put(word, new ArrayList<String>());
dict.add(word);
}
q.add(beginWord);
distance.put(beginWord, 0);
while(!q.isEmpty()){
String cur = q.poll();
List<String> nextWords = getNextWord(cur, dict);
for(String s : nextWords){
father.get(s).add(cur);//新的word都是在字典里的,所以father不必判断,可以得到所有情况
if(!distance.containsKey(s)){//字典里并非所有字母都可达,所以需要判断,这里也是为了去重。
distance.put(s, distance.get(cur) + 1);//第一个到的就是最短的,后来的不要再加了,会越来越大的。
q.offer(s);
}
}
}
}
}