classSolution { public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { if (!wordList.contains(endWord)) { returnnewArrayList<>(); }
// key: word // value: the word list which can transfer from the word with change only one letter Map<String, Set<String>> transferMap = newHashMap<>();
wordList.add(0, beginWord); for (inti=0; i < wordList.size(); i++) { Stringcurrent= wordList.get(i); Set<String> currentWords = transferMap.getOrDefault(current, newHashSet<>()); transferMap.put(current, currentWords); for (intj= i + 1; j < wordList.size(); j++) { Stringnext= wordList.get(j); Set<String> nextWords = transferMap.getOrDefault(next, newHashSet<>()); transferMap.put(next, nextWords); if (isValid(current, next)) { currentWords.add(next); nextWords.add(current); } } } wordList.remove(0);
Set<String> used = newHashSet<>(); booleanisFind=false; List<List<String>> result = newLinkedList<>(); Queue<List<String>> queue = newLinkedList<>(); queue.offer(Arrays.asList(beginWord)); while (!queue.isEmpty() && !isFind) { for (inti= queue.size(); i > 0; i--) { List<String> currentList = queue.poll(); StringcurrentWord= currentList.get(currentList.size() - 1); used.add(currentWord); if (currentWord.equals(endWord)) { result.add(currentList); isFind = true; continue; }
// can not traversal the wordList, or it will be time Time Limit Exceeded for (String word : transferMap.get(currentWord)) { if (!used.contains(word)) { List<String> next = newLinkedList<>(currentList); next.add(word); queue.offer(next); } } } }
return result; }
privatebooleanisValid(String word, String other) { intcount=0; intlength= word.length(); for (inti=0; i < length; i++) { if (word.charAt(i) != other.charAt(i)) { count++; }