-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWordLadder.java
More file actions
120 lines (101 loc) · 3.61 KB
/
WordLadder.java
File metadata and controls
120 lines (101 loc) · 3.61 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package leetcode;
import java.util.*;
import java.util.concurrent.LinkedTransferQueue;
/**
* WordLadder
* https://leetcode-cn.com/problems/word-ladder/
* 127. 单词接龙
*
* @since 2020-11-05
*/
public class WordLadder {
public static void main(String[] args) {
String beginWord = "hit";
String endWord = "cog";
String[] wordList = {"hot", "dot", "dog", "lot", "log", "cog"};
WordLadder sol = new WordLadder();
System.out.println(sol.ladderLength(beginWord, endWord, Arrays.asList(wordList)));
}
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
if (wordList == null || wordList.size() < 1) {
return 0;
}
Set<Integer>[] nextWords = new Set[wordList.size() + 1];
for (int idx = 0; idx < wordList.size() + 1; idx++) {
nextWords[idx] = new HashSet<>();
}
int endIdx = buildGraph(beginWord, wordList, endWord, nextWords);
if (endIdx < 0) {
return 0;
}
return dijkstra(nextWords.length - 1, endIdx, nextWords);
}
private int dijkstra(int beginIdx, int endIdx, Set<Integer>[] nextWords) {
int[] shortest = new int[nextWords.length];
for (int idx = 0; idx < nextWords.length; idx++) {
shortest[idx] = Integer.MAX_VALUE;
}
Queue<Integer> nodeQueue = new LinkedTransferQueue<>();
nodeQueue.add(beginIdx);
shortest[beginIdx] = 1;
while (!nodeQueue.isEmpty()) {
int currIdx = nodeQueue.poll();
if (currIdx == endIdx) {
continue;
}
int nextLength = shortest[currIdx] + 1;
for (Integer nextIdx : nextWords[currIdx]) {
if (shortest[nextIdx] > nextLength) {
shortest[nextIdx] = nextLength;
nodeQueue.add(nextIdx);
}
}
}
// 例外情况:
// "hot"
// "dog"
// ["hot","dog"]
return shortest[endIdx] == Integer.MAX_VALUE ? 0 : shortest[endIdx];
}
private int buildGraph(String beginWord, List<String> wordList, String endWord, Set<Integer>[] nextWords) {
int endIdx = -1;
for (int startIdx = 0; startIdx < wordList.size(); startIdx++) {
String start = wordList.get(startIdx);
if (start.equals(endWord)) {
endIdx = startIdx;
}
for (int nextIdx = startIdx + 1; nextIdx < wordList.size(); nextIdx++) {
String next = wordList.get(nextIdx);
if (isNeighbor(start, next)) {
nextWords[startIdx].add(nextIdx);
nextWords[nextIdx].add(startIdx);
}
}
}
int startIdx = wordList.size();
String start = beginWord;
for (int nextIdx = 0; nextIdx < wordList.size(); nextIdx++) {
String next = wordList.get(nextIdx);
if (isNeighbor(start, next)) {
nextWords[startIdx].add(nextIdx);
nextWords[nextIdx].add(startIdx);
}
}
return endIdx;
}
private boolean isNeighbor(String start, String end) {
if (start == null || end == null || start.length() != end.length()) {
return false;
}
int diffCount = 0;
for (int idx = 0; idx < start.length(); idx++) {
if (start.charAt(idx) != end.charAt(idx)) {
diffCount++;
if (diffCount > 1) {
return false;
}
}
}
return true;
}
}