https://leetcode.com/problems/word-ladder-ii/#/description
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWordto endWord, such that:
- Only one letter can be changed at a time
- Each transformed word must exist in the word list. Note that 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"] ]
Note:
- Return an empty list if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
package go.jacob.day727;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
/**
* 126. Word Ladder II
* 思路:图bfs的应用
* @author Jacob
*
*/
public class Demo2 {
// res为最终结果
List<List<String>> res;
Map<String, List<String>> map;
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
res = new ArrayList<List<String>>();
if (wordList.size() == 0)
return res;
// 最小步数初始化为最大值
int min = Integer.MAX_VALUE;
Queue<String> queue = new LinkedList<String>();
queue.add(beginWord);
map = new HashMap<String, List<String>>();
// ladder用来记录每个string出现的最小序号
Map<String, Integer> ladder = new HashMap<String, Integer>();
for (String string : wordList)
// 初始化为最大值
ladder.put(string, Integer.MAX_VALUE);
ladder.put(beginWord, 0);
wordList.add(endWord);
while (!queue.isEmpty()) {
String word = queue.poll();
int step = ladder.get(word) + 1;
// 如果大于最小步数,直接跳出循环
if (step > min)
break;
for (int i = 0; i < word.length(); i++) {
StringBuilder sb = new StringBuilder();
for (char c = 'a'; c <= 'z'; c++) {
sb.setCharAt(i, c);
String new_word = sb.toString();
if (ladder.containsKey(new_word)) {
// 只有第一遍历到的new_word才会加入到queue,map,因为step是非递减的
if (step > ladder.get(new_word))
continue;
else if (step < ladder.get(new_word)) {
queue.add(new_word);
ladder.put(new_word, step);
} else
;
// map中只存放word的所有前一个元素
if (map.containsKey(new_word))
map.get(new_word).add(word);
else {
List<String> list = new LinkedList<String>();
list.add(word);
map.put(new_word, list);
}
if (new_word.equals(endWord))
min = step;
}
}
}
}
//只能用LinkedList,不能用ArrayList。原因见backTrace方法
LinkedList<String> result = new LinkedList<String>();
backTrace(endWord, beginWord, result);
return res;
}
private void backTrace(String word, String start, List<String> list) {
if (word.equals(start)) {
list.add(0, start);
res.add(new ArrayList<String>(list));
list.remove(0);
return;
}
//注意:这里的list是LinkedList类型,所以插入index=0的位置,其余元素全部后移
//如果是ArrayList,会把0处的元素替换
list.add(0, word);
if (map.get(word) != null)
for (String s : map.get(word))
backTrace(s, start, list);
list.remove(0);
}
}