You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.4 KiB

2 years ago
package class31;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Problem_0127_WordLadder {
// start出发的单词
// to, 目标单位
// list, 列表
// to 一定属于list
// start未必
// 返回变幻的最短路径长度
public static int ladderLength1(String start, String to, List<String> list) {
list.add(start);
// key : 列表中的单词,每一个单词都会有记录!
// value : key这个单词有哪些邻居
HashMap<String, ArrayList<String>> nexts = getNexts(list);
// abc 出发 abc -> abc 0
//
// bbc 1
HashMap<String, Integer> distanceMap = new HashMap<>();
distanceMap.put(start, 1);
HashSet<String> set = new HashSet<>();
set.add(start);
Queue<String> queue = new LinkedList<>();
queue.add(start);
while (!queue.isEmpty()) {
String cur = queue.poll();
Integer distance = distanceMap.get(cur);
for (String next : nexts.get(cur)) {
if (next.equals(to)) {
return distance + 1;
}
if (!set.contains(next)) {
set.add(next);
queue.add(next);
distanceMap.put(next, distance + 1);
}
}
}
return 0;
}
public static HashMap<String, ArrayList<String>> getNexts(List<String> words) {
HashSet<String> dict = new HashSet<>(words);
HashMap<String, ArrayList<String>> nexts = new HashMap<>();
for (int i = 0; i < words.size(); i++) {
nexts.put(words.get(i), getNext(words.get(i), dict));
}
return nexts;
}
// 应该根据具体数据状况决定用什么来找邻居
// 1)如果字符串长度比较短,字符串数量比较多,以下方法适合
// 2)如果字符串长度比较长,字符串数量比较少,以下方法不适合
public static ArrayList<String> getNext(String word, HashSet<String> dict) {
ArrayList<String> res = new ArrayList<String>();
char[] chs = word.toCharArray();
for (int i = 0; i < chs.length; i++) {
for (char cur = 'a'; cur <= 'z'; cur++) {
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;
}
public static int ladderLength2(String beginWord, String endWord, List<String> wordList) {
HashSet<String> dict = new HashSet<>(wordList);
if (!dict.contains(endWord)) {
return 0;
}
HashSet<String> startSet = new HashSet<>();
HashSet<String> endSet = new HashSet<>();
HashSet<String> visit = new HashSet<>();
startSet.add(beginWord);
endSet.add(endWord);
for (int len = 2; !startSet.isEmpty(); len++) {
// startSet是较小的endSet是较大的
HashSet<String> nextSet = new HashSet<>();
for (String w : startSet) {
// w -> a(nextSet)
// a b c
// 0
// 1
// 2
for (int j = 0; j < w.length(); j++) {
char[] ch = w.toCharArray();
for (char c = 'a'; c <= 'z'; c++) {
if (c != w.charAt(j)) {
ch[j] = c;
String next = String.valueOf(ch);
if (endSet.contains(next)) {
return len;
}
if (dict.contains(next) && !visit.contains(next)) {
nextSet.add(next);
visit.add(next);
}
}
}
}
}
// startSet(小) -> nextSet(某个大小) 和 endSet大小来比
startSet = (nextSet.size() < endSet.size()) ? nextSet : endSet;
endSet = (startSet == nextSet) ? endSet : nextSet;
}
return 0;
}
}