[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
当要返回所有 path 的时候,细节处理就更多了。其实这题和 Longest Increasing Subsequence 的 follow-up ,返回所有 LIS 有相通的地方,都是维护一个 Directed Graph 关系并且从某一个终点进行 dfs 返回所有 valid path.
Map<String, Integer> dist = new HashMap<>(); ---- 单词节点到起点的距离
Map<String, List<String>> map = new HashMap<>(); ---- graph的邻接表示
List<String> path = new ArrayList<>(); ---- 路径
public class Solution {
/*
* @param start: a string
* @param end: a string
* @param dict: a set of string
* @return: a list of lists of string
*/
public List<List<String>> findLadders(String start, String end, Set<String> dict) {
// write your code here
List<List<String>> res = new ArrayList<>();
// if (!dict.contains(end)) {
// return res;
// }
dict.add(start);
dict.add(end);
Map<String, Integer> dist = new HashMap<>();
Map<String, List<String>> map = new HashMap<>();
List<String> path = new ArrayList<>();
bfs(start, end, dict, dist, map);
dfs(end, start, res, path, dist, map);
return res;
}
private List<String> getNextWords(String word, Set<String> dict) {
List<String> nextWords = new ArrayList<>();
for (int i = 0; i < word.length(); i++) {
for (char c = 'a'; c <= 'z'; c++) {
if (c == word.charAt(i)) {
continue;
}
String newWord = replace(word, i, c);
if (dict.contains(newWord)) {
nextWords.add(newWord);
}
}
}
return nextWords;
}
private String replace(String s, int index, char c) {
char[] ch = s.toCharArray();
ch[index] = c;
return String.valueOf(ch);
}
private void bfs(String start, String end,
Set<String> dict,
Map<String, Integer> dist,
Map<String, List<String>> map) {
dist.put(start, 0);
for (String ss : dict) {
map.put(ss, new ArrayList<String>());
}
Queue<String> q = new LinkedList<>();
q.offer(start);
while (!q.isEmpty()) {
String curr = q.poll();
List<String> nextList = getNextWords(curr, dict);
for (String next : nextList) {
map.get(next).add(curr);
if (!dist.containsKey(next)) {
dist.put(next, dist.get(curr) + 1);
q.offer(next);
}
}
}
}
private void dfs(String curr, String start,
List<List<String>> res,
List<String> path,
Map<String, Integer> dist,
Map<String, List<String>> map) {
path.add(curr);
if (curr.equals(start)) {
Collections.reverse(path);
res.add(new ArrayList<String>(path));
Collections.reverse(path);
} else {
for (String next : map.get(curr)) {
if (dist.containsKey(next)
&& dist.get(curr) == dist.get(next) + 1) {
dfs(next, start, res, path, dist, map);
}
}
}
path.remove(path.size() - 1);
}
}