题目
给定字典中的两个词,长度相等。写一个方法,把一个词转换成另一个词, 但是一次只能改变一个字符。每一步得到的新词都必须能在字典中找到。
编写一个程序,返回一个可能的转换序列。如有多个可能的转换序列,你可以返回任何一个。
示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
输出:
["hit","hot","dot","lot","log","cog"]
1
2
3
4
5
6
7
2
3
4
5
6
7
示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
输出: []
解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
题解
java
public List<String> findLadders(String beginWord, String endWord, List<String> wordList) {
Set<String> words = new HashSet<>(wordList);
// 开始单词或结束单词不存在与字典中
if (!words.contains(endWord)) {
return Collections.emptyList();
}
// 是否满足转换条件 两个单词只能有一个字母不同
BiPredicate<String, String> isCondition = (s, t) -> {
int len = s.length(), cnt = 0;
for (int i = 0; i < len; i++) {
if (s.charAt(i) != t.charAt(i)) {
cnt++;
if (cnt > 1) {
return false;
}
}
}
return cnt == 1;
};
List<String> result = new ArrayList<>(), dict = new ArrayList<>(words);
int len = dict.size();
// 标记已经使用过的单词
int[] visited = new int[len];
Function<String, Boolean> backtrack = new Function<String, Boolean>() {
@Override
public Boolean apply(String prefix) {
result.add(prefix);
if (Objects.equals(prefix, endWord)) {
return true;
}
for (int i = 0; i < len; i++) {
String word = dict.get(i);
if (visited[i] == 0 && isCondition.test(prefix, word)) {
visited[i] = 1;
Boolean apply = this.apply(word);
// 找到解 直接结束
if (apply) {
return true;
}
// 回溯
result.remove(result.size() - 1);
}
}
return false;
}
};
if (backtrack.apply(beginWord)) {
return new ArrayList<>(result);
}
return Collections.emptyList();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58