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) {
List<List<String>> rst = new ArrayList<List<String>>();
/**
* 各个点的连接情况
* 每个点的上面都有哪些点
*/
Map<String, List<String>> map = new HashMap<String, List<String>>();
/**
* 每一个点到起点的最短距离
*/
Map<String, Integer> distance = new HashMap<String, Integer>();
dict.add(start);
dict.add(end);
bfs(map, distance, start, end, dict);
List<String> path = new ArrayList<String>();
path.add(end); // 先在路径中加上终点
dfs(rst, path, end, start, distance, map);
return rst;
}
/**
* 通过map distance找出所有最短路径
* 从 终点 向 起点 找
*/
void dfs(List<List<String>> rst, List<String> path, String crt,
String start, Map<String, Integer> distance,
Map<String, List<String>> map) {
// 递归的退出条件
if (crt.equals(start)) {
Collections.reverse(path);
rst.add(new ArrayList<String>(path)); // 找到一个最短路径
Collections.reverse(path);
return;
}
// 遍历crt上面的点
for (String next : map.get(crt)) {
if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) {
// 这是一个正确的方向,继续向上找
path.add(next); // 从 终点 向 起点
dfs(rst, path, next, start, distance, map);
path.remove(path.size() - 1);
}
}
}
/**
* 广度优先搜索
* 从上至下遍历
* 填充 map distance
*/
void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
String start, String end, Set<String> dict) {
Queue<String> queue = new ArrayDeque<String>();
queue.offer(start);
distance.put(start, 0);
for (String s : dict) {
// dict中的每一个词都对应一个数组
map.put(s, new ArrayList<String>());
}
// 从上至下层序遍历
while (!queue.isEmpty()) {
String crt = queue.poll(); // 不会重复遍历相同的crt
List<String> nextList = expand(crt, dict);
for (String next : nextList) {
map.get(next).add(crt); //填充map
if (!distance.containsKey(next)) {
// 填充distance,这个点到起点的最短路径
distance.put(next, distance.get(crt) + 1);
queue.offer(next); // 遍历过的点不会再被遍历
}
}
}
}
/**
* 返回一个数组,数组元素为String
* 这个数组包含了crt的所有可能的拓展
* 该数组中所有的元素都必须是dict中的元素
*/
List<String> expand(String crt, Set<String> dict) {
List<String> expansion = new ArrayList<String>();
for (int i = 0; i < crt.length(); i++) {
for (char ch = 'a'; ch <= 'z'; ch++) {
if (ch != crt.charAt(i)) {
String expanded = crt.substring(0, i) + ch
+ crt.substring(i + 1);
if (dict.contains(expanded)) {
expansion.add(expanded); // 放入数组
}
}
}
}
return expansion;
}
}
[刷题]Word Ladder II
最新推荐文章于 2020-12-17 15:16:22 发布