WordLadder2
Hard
- 将wordList里面的元素放到Set dict()里,查找时间可以优化至O(1), 很简单的代码
Set<String> dict = new HashSet<>(wordList);
- 一个单词(String)可以转化成什么其他的单词(List)-> 映射关系
- 过程中的映射关系, 用HashMap表示
- 用BFS去填充map,把所有情况走一遍
- tmp set 用来更新 start set
- 把startSet里单词从dict里删除,所有开始的单词都不会再用到
- 修改String中的单独字母,转化为 charArray()
for(String s : startSet){
char[] chs = s.toCharArray();
...
}
- 修改完将新单词存在一个新String word里, 这样可以保证原来的String 是不变, 便于之后的back tracking
String word = new String(chs);
- 验证在dict里的新单词: 如果是endWord - 结束; 如果不是 - 放入tmp中, 作为下一次进入BFS的startSet
- 如果s不在map就先添加key和空value - (new ArrayList()) 之后把变化出来的新单词加到arrayList里
- 把一个单词的一位,从a-z改完一遍后,记得把这位还原回原来的字母
- 用DFS去生成结果
- base case: word 等于 endWord 结果加上deep copy的单词list,deep copy原因是list是reference, 会随着后面的back tracking不断变化
- 或者 map里当前word没有value, 意味着没有可演变的单词, 又不等于endWord,只能 return
- DFS主体: 循环每个map value 的 list 中的每个单词, 每个单词再找它们对应的value
- 删除最后一个元素:在backtacking向上回溯的时候,需要一步一步地删除以前加入的元素,如果没有这一句的话,那么上一条路径的solution也会一直保存在solution中(来源:blog.csdn.net/shenzhu0127… )
代码
class Solution {
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
List<List<String>> res = new ArrayList<>();
Set<String> dict = new HashSet<>(wordList);
if(!dict.contains(endWord))
return res;
Map<String, List<String>> map = new HashMap<>();
Set<String> startSet = new HashSet<>();
startSet.add(beginWord);
bfs(startSet, endWord, map, dict);
List<String> list = new ArrayList<>();
list.add(beginWord);
dfs(res, list, endWord, beginWord, map);
return res;
}
private void dfs(List<List<String>> res, List<String> list, String endWord, String word, Map<String, List<String>> map){
if(word.equals(endWord)){
res.add(new ArrayList(list));
return;
}
if(map.get(word) == null) return;
for(String s : map.get(word)){
list.add(s);
dfs(res, list, endWord, s, map);
list.remove(list.size() - 1);
}
}
private void bfs(Set<String> startSet, String endWord, Map<String, List<String>> map, Set<String> dict){
if(startSet.size() == 0) return;
Set<String> tmp = new HashSet<>();
boolean finish = false;
dict.removeAll(startSet);
for(String s : startSet){
char[] chs = s.toCharArray();
for(int i = 0; i < chs.length; i++){
char old = chs[i];
for(char c = 'a'; c <= 'z'; c++){
chs[i] = c;
String word = new String(chs);
if(dict.contains(word)){
if(endWord.equals(word)){
finish = true;
}else{
tmp.add(word);
}
if(map.get(s) == null){
map.put(s, new ArrayList<>());
}
map.get(s).add(word);
}
}
chs[i] = old;
}
}
if(!finish){
bfs(tmp, endWord, map, dict);
}
}
}
BFS, DFS, back tracking, HashMap