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
| class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { Set<String> wordSet = new HashSet<>(wordList); if (!wordSet.contains(endWord)) { return 0; }
Queue<String> queueA = new LinkedList<>(); queueA.add(beginWord); Queue<String> queueB = new LinkedList<>(); queueB.add(endWord);
Map<String, Integer> wordToEdgeCountMapA = new HashMap<>(); wordToEdgeCountMapA.put(beginWord, 0); Map<String, Integer> wordToEdgeCountMapB = new HashMap<>(); wordToEdgeCountMapB.put(endWord, 0);
while (!queueA.isEmpty() && !queueB.isEmpty()) { int edgeCount;
if (queueA.size() <= queueB.size()) { edgeCount = tryConnect(wordSet, queueA, wordToEdgeCountMapA, wordToEdgeCountMapB); } else { edgeCount = tryConnect(wordSet, queueB, wordToEdgeCountMapB, wordToEdgeCountMapA); }
if (edgeCount != -1) { return edgeCount + 1; } }
return 0; }
private int tryConnect(Set<String> wordSet, Queue<String> queue, Map<String, Integer> wordToEdgeCountMap, Map<String, Integer> otherWordToEdgeCountMap) { for (int i = queue.size(); i > 0; i--) { String word = queue.poll(); int edgeCount = wordToEdgeCountMap.get(word);
char[] chars = word.toCharArray(); for (int j = 0; j < chars.length; j++) { char sourceChar = chars[j]; for (char c = 'a'; c <= 'z'; c++) { if (c == sourceChar) { continue; }
chars[j] = c; String nextWord = new String(chars); if (wordToEdgeCountMap.containsKey(nextWord) && wordToEdgeCountMap.get(nextWord) <= edgeCount + 1) { continue; } if (wordSet.contains(nextWord)) { if (otherWordToEdgeCountMap.containsKey(nextWord)) { return edgeCount + 1 + otherWordToEdgeCountMap.get(nextWord); } queue.offer(nextWord); wordToEdgeCountMap.put(nextWord, edgeCount + 1); } } chars[j] = sourceChar; } }
return -1; } }
|