Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["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.
和 I 类似,还是要BFS, 但这次要储存路径,用一个二维数组先储存BFS每一层的String, 然后再DFS数组,找出路径。
例如 :
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
BFS 每层的String分别为:
[hit]
[hot]
[lot, dot]
[log, dog]
[cog]
这道题其实可以把所有的单词转换成一个无向图中的节点,算出每个节点的邻居,然后用 Dijkstra算法算出最短路径就可以了。
public static ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict){
Map<String, Integer> map = new HashMap<>();
Map<String, Set<String>> preWordMap = new HashMap<>();
map.put(start, 0);
Queue<String> queue = new LinkedList<>();
queue.add(start);
Set<String> visit = new HashSet<>();
while (!queue.isEmpty()) {
String s = queue.poll();
if (visit.contains(s))
continue;
visit.add(s);
Set<String> set = strList(s, dict);
for (String str : set) {
queue.add(str);
int count = map.get(s);
if (map.get(str)==null || map.get(str)==count+1){
map.put(str, count + 1);
if(preWordMap.get(str) == null){
Set<String> subSet = new HashSet<>();
subSet.add(s);
preWordMap.put(str,subSet);
}else{
Set<String> subSet = preWordMap.get(str);
subSet.add(s);
preWordMap.put(str,subSet);
}
}
}
}
int min = Integer.MAX_VALUE;
Set<String> resultSet = new HashSet<>();
Set<String> endSet = strList(end, dict);
for (String s : endSet) {
int i = map.get(s);
if (i < min){
resultSet.clear();
resultSet.add(s);
min = i;
}else if (i== min){
resultSet.add(s);
}
}
preWordMap.put(end,resultSet);
ArrayList<ArrayList<String>> list = new ArrayList<>();
ArrayList<String> l = new ArrayList<>();
helper(end, end, preWordMap, list, l);
return list;
}
private static void helper(String str,String end, Map<String,Set<String>> preWordMap, ArrayList<ArrayList<String>> list, ArrayList<String> l){
Set<String> set = preWordMap.get(str);
if(set == null){
ArrayList<String> newList = new ArrayList<>(l);
Collections.reverse(newList);
newList.add(end);
list.add(newList);
return;
}
for(String s: set){
l.add(s);
helper(s,end,preWordMap,list,l);
l.remove(l.size()-1);
}
}