package class26; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Queue; // 本题测试链接 : https://leetcode.com/problems/word-ladder-ii/ public class Code04_WordLadderII { public static List> findLadders(String start, String end, List list) { list.add(start); HashMap> nexts = getNexts(list); HashMap fromDistances = getDistances(start, nexts); List> res = new ArrayList<>(); if (!fromDistances.containsKey(end)) { return res; } HashMap toDistances = getDistances(end, nexts); LinkedList pathList = new LinkedList<>(); getShortestPaths(start, end, nexts, fromDistances, toDistances, pathList, res); return res; } public static HashMap> getNexts(List words) { HashSet dict = new HashSet<>(words); HashMap> nexts = new HashMap<>(); for (int i = 0; i < words.size(); i++) { nexts.put(words.get(i), getNext(words.get(i), dict)); } return nexts; } // word, 在表中,有哪些邻居,把邻居们,生成list返回 public static List getNext(String word, HashSet dict) { ArrayList res = new ArrayList(); char[] chs = word.toCharArray(); for (char cur = 'a'; cur <= 'z'; cur++) { for (int i = 0; i < chs.length; i++) { if (chs[i] != cur) { char tmp = chs[i]; chs[i] = cur; if (dict.contains(String.valueOf(chs))) { res.add(String.valueOf(chs)); } chs[i] = tmp; } } } return res; } // 生成距离表,从start开始,根据邻居表,宽度优先遍历,对于能够遇到的所有字符串,生成(字符串,距离)这条记录,放入距离表中 public static HashMap getDistances(String start, HashMap> nexts) { HashMap distances = new HashMap<>(); distances.put(start, 0); Queue queue = new LinkedList<>(); queue.add(start); HashSet set = new HashSet<>(); set.add(start); while (!queue.isEmpty()) { String cur = queue.poll(); for (String next : nexts.get(cur)) { if (!set.contains(next)) { distances.put(next, distances.get(cur) + 1); queue.add(next); set.add(next); } } } return distances; } // cur 当前来到的字符串 可变 // to 目标,固定参数 // nexts 每一个字符串的邻居表 // cur 到开头距离5 -> 到开头距离是6的支路 fromDistances距离表 // cur 到结尾距离5 -> 到开头距离是4的支路 toDistances距离表 // path : 来到cur之前,深度优先遍历之前的历史是什么 // res : 当遇到cur,把历史,放入res,作为一个结果 public static void getShortestPaths(String cur, String to, HashMap> nexts, HashMap fromDistances, HashMap toDistances, LinkedList path, List> res) { path.add(cur); if (to.equals(cur)) { res.add(new LinkedList(path)); } else { for (String next : nexts.get(cur)) { if (fromDistances.get(next) == fromDistances.get(cur) + 1 && toDistances.get(next) == toDistances.get(cur) - 1) { getShortestPaths(next, to, nexts, fromDistances, toDistances, path, res); } } } path.pollLast(); } }