题目:Word Ladder
难度:hard
问题描述:
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.
测试案例属于短而巨多字符串。因此,在一开始使用DFS直接超时了额。于是想到继续用BFS,同时使用map记录每个字符串的前向节点。最后使用回溯找到所有的解。
代码如下:
public class h_126_WordLadderll {
HashMap<String,List<String>> lastmap;
public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
//记录该Str的上一层节点
lastmap=new HashMap<>();
lastmap.put(endWord, new ArrayList<>());
//记录该Str是哪一层
HashMap<String,Integer> intmap=new HashMap<>();
for(String w:wordList){
intmap.put(w, Integer.MAX_VALUE);
}
intmap.put(endWord, Integer.MAX_VALUE);
wordList.add(endWord);
//BFS的queue
Queue<String> queue=new ArrayDeque<>();
queue.add(beginWord);
int level=0;
int min=Integer.MAX_VALUE;
while(!queue.isEmpty()){
int len=queue.size();//该层的节点数
level++;
if(level>min) break;
for(int i=0;i<len;i++){
String str=queue.poll();
for(int j=0;j<str.length();j++){
char[] cs=str.toCharArray();
for(char c='a';c<='z';c++){
cs[j]=c;
String newstr=new String(cs);
if(wordList.contains(newstr)){
if(level<intmap.get(newstr)){
queue.add(newstr);
intmap.put(newstr, level);
}else if(level>intmap.get(newstr)){
continue;
}
if(lastmap.containsKey(newstr)){
lastmap.get(newstr).add(str);
}else{
List<String> list= new LinkedList<String>();
list.add(str);
lastmap.put(newstr, list);
}
if (newstr.equals(endWord)){
min=level;
}
}
}
}
}
}
for(String w:lastmap.keySet()){
System.out.print(w+":");
for(String x:lastmap.get(w)){
System.out.print(x+"-");
}
System.out.println();
}
List<List<String>> results= new ArrayList<List<String>>();
List<String> result=new ArrayList<>();
DFS(endWord,beginWord,result,results);
return results;
}
private void DFS(String endWord,String beginWord,List<String> result,List<List<String>> results){
if(endWord.equals(beginWord)){
result.add(0,beginWord);
results.add(new ArrayList<>(result));
result.remove(0);
return ;
}
result.add(0,endWord);
if(lastmap.get(endWord)!=null){
for(String s:lastmap.get(endWord)){
DFS(s,beginWord,result,results);
}
}
result.remove(0);
}
public static void main(String[]args){
h_126_WordLadderll s=new h_126_WordLadderll();
Set<String> wordList=new HashSet<>();
wordList.add("hot");
wordList.add("lot");
wordList.add("dot");
wordList.add("log");
wordList.add("dog");
String begin="hit";
String end="cog";
List<List<String>> res= s.findLadders(begin, end, wordList);
for(List<String> w:res){
for(String st:w){
System.out.print(st+"-");
}
System.out.println();
}
}
}