Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
分析: 首先用一个全局的map结构存储出现再单词词典中出现的词以及哪些已访问的单词能通过改变一个字母得到它便于回溯。
然后维持一个最小步数的变量,初始化为最大值,只有当出现当前单词等于刚开始的那个单词时,更新变量,每次循环时,应该比较当前所消耗的步数是否大于最小值(这样可以集合所有步数等于最小值的情况)若大于的话,则调处循环,用一个队列存储之前通过改变一个字母且在字典中的单词。
public class Solution {
HashMap<String,List<String>> map;
List<List<String>> ans;
public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
ans=new ArrayList<List<String>>();
if(wordList==null)
return ans;
map=new HashMap<String,List<String>>();
int min_step=Integer.MAX_VALUE;
HashMap<String,Integer> word_len=new HashMap<String,Integer>();
for(String word:wordList){
word_len.put(word,Integer.MAX_VALUE);
}
word_len.put(beginWord,0);
Queue<String> queue=new ArrayDeque<String>();
queue.add(beginWord);
while(!queue.isEmpty()){
String word=queue.poll();
int index=word_len.get(word)+1;
if(index>min_step)
break;
for(int i=0;i<word.length();i++){
StringBuilder sb=new StringBuilder(word);
for(char ch='a';ch<='z';ch++){
sb.setCharAt(i,ch);
String new_word=sb.toString();
if(word_len.containsKey(new_word)){
int num=word_len.get(new_word);
if(num<index)
continue;
else if(num>index){
word_len.put(new_word,index);
queue.add(new_word);
}
if(!map.containsKey(new_word)){
map.put(new_word,new ArrayList<String>());
}
map.get(new_word).add(word);
if(new_word.equals(endWord))
min_step=index;
}
}
}
}
findLadder(endWord,beginWord,new ArrayList<String>());
return ans;
}
public void findLadder(String wordEnd,String wordStart,ArrayList<String> list){
if(wordEnd.equals(wordStart)){
list.add(0,wordEnd);
ans.add(new ArrayList<String>(list));
list.remove(0);
return;
}
list.add(0,wordEnd);
if(map.get(wordEnd)!=null){
for(String word:map.get(wordEnd)){
findLadder(word,wordStart,list);
}
}
list.remove(0);
}
}