126 word ladder II
class Solution {
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
Queue<String> queue = new ArrayDeque<>();
List<List<String>> ans = new ArrayList<>();
Set<String> dict = new HashSet<>(wordList);
//for backtracking,这里要用set防止重复parent
Map<String, Set<String>> map = new HashMap<>();
Set<String> visited = new HashSet<>();
queue.offer(beginWord);
visited.add(beginWord);
boolean found = false;
while(!queue.isEmpty()) {
if (found) break;
int size = queue.size();
//思想就是每一层用tmpVisited暂存一下visited,主要是因为这一层是允许重复的
//即允许这一层的不同word生成相同的下一层word(因为要得到所有路径嘛),
//但是不允许这一层word在之前层中出现过
Set<String> tmpVisited = new HashSet<>();
for (int aa = 0; aa < size; aa++) {
String str = queue.poll();
if (str.equals(endWord)) {
found = true;
continue;
}
char[] array = str.toCharArray();
for (int i = 0; i < array.length; i++) {
char ch = array[i];
for (int j = 0; j < 26; j++) {
if (j == ch - 'a') continue;
array[i] = (char)('a' + j);
String newStr = new String(array);
if (!dict.contains(newStr) || visited.contains(newStr)) continue;
tmpVisited.add(newStr);
Set<String> parents = map.get(newStr);
if (parents == null) parents = new HashSet<>();
parents.add(str);
map.put(newStr, parents);
queue.offer(newStr);
}
array[i] = ch;
}
}
visited.addAll(tmpVisited);
}
if (!found) return ans;
dfs(ans, map, new ArrayList<>(), endWord, beginWord);
return ans;
}
private void dfs(List<List<String>> ans, Map<String, Set<String>> map, List<String> res,
String endWord, String beginWord) {
if (endWord.equals(beginWord)) {
res.add(endWord);
List<String> revres = new ArrayList<>(res);
// Collections里面有reverse api
Collections.reverse(revres);
ans.add(new ArrayList<>(revres));
// 注意这里也是要remove的 返回上一层之前都要remove
// 你要是不想的话就不要在原来的上面add,reverse之后再把beginword add上去
res.remove(endWord);
return;
}
Set<String> list = map.get(endWord);
// 防止没有可行解时npe
if (list == null) return;
res.add(endWord);
for (String str : list) {
dfs(ans, map, res, str, beginWord);
}
res.remove(res.size() - 1);
}
}
这题的时间要求太操蛋了,但是核心思想就是暂存visited来允许重复
如何获得所有路径:bfs自身善于获得最短路径长度,但是并不擅长记录走过的路径,需要记录当前string和能得到它的parents,然后通过dfs倒着从结果倒推出找出所有路径
同时注意如果要backtrack的话map应该记录什么
Last updated