Word Ladder II
Given two words (beginWordandendWord), and a dictionary's word list, find all shortest transformation sequence(s) frombeginWordtoendWord, such that:
Only one letter can be changed at a time
Each transformed word must exist in the word list. Note tha beginWord is not a transformed word.
For example,
Given:
beginWord="hit"
endWord="cog"
wordList=["hot","dot","dog","lot","log","cog"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
分析
BFS得到所有最短路径, DFS遍历输出
BFS 其中用map father保存路径,用字典里所有words做key,然后存储所有可到word的father点,father放在list里。
Distance用法妙极,在BFS里可以判重,在DFS里判断最短路径。
BFS里第一次遇到的word直接存入distance里,因为将来再遇到只会路径只会更长。同时也用来判重,再者distance不像father里所有字典里的word都在father的keyset里。distance里不一定包含字典里所有words,因为word不一定可达。
DFS里Collections.reverse(List l)
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);
}
}
}
}
}
Last updated
Was this helpful?