Approach
Breadth-first search
For Word Ladder II, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 85 lines of Java from the credited upstream file 126.java.
- The implementation visibly relies on sequence storage, hash lookup, ordered lookup.
- 7 loop blocks detected, together with recursive traversal.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {3 Set<String> wordSet = new HashSet<>(wordList);4 if (!wordSet.contains(endWord))5 return new ArrayList<>();6 7 8 Map<String, List<String>> graph = new HashMap<>();9 10 11 if (!bfs(beginWord, endWord, wordSet, graph))12 return new ArrayList<>();13 14 List<List<String>> ans = new ArrayList<>();15 List<String> path = new ArrayList<>(List.of(beginWord));16 dfs(graph, beginWord, endWord, path, ans);17 return ans;18 }19 20 private boolean bfs(final String beginWord, final String endWord, Set<String> wordSet,21 Map<String, List<String>> graph) {22 Set<String> currentLevelWords = new HashSet<>();23 currentLevelWords.add(beginWord);24 boolean reachEndWord = false;25 26 while (!currentLevelWords.isEmpty()) {27 for (final String word : currentLevelWords)28 wordSet.remove(word);29 Set<String> nextLevelWords = new HashSet<>();30 for (final String parent : currentLevelWords) {31 graph.putIfAbsent(parent, new ArrayList<>());32 for (final String child : getChildren(parent, wordSet)) {33 if (wordSet.contains(child)) {34 nextLevelWords.add(child);35 graph.get(parent).add(child);36 }37 if (child.equals(endWord))38 reachEndWord = true;39 }40 }41 if (reachEndWord)42 return true;43 currentLevelWords = nextLevelWords;44 }45 46 return false;47 }48 49 private List<String> getChildren(final String parent, Set<String> wordSet) {50 List<String> children = new ArrayList<>();51 StringBuilder sb = new StringBuilder(parent);52 53 for (int i = 0; i < sb.length(); ++i) {54 final char cache = sb.charAt(i);55 for (char c = 'a'; c <= 'z'; ++c) {56 if (c == cache)57 continue;58 sb.setCharAt(i, c);59 final String child = sb.toString();60 if (wordSet.contains(child))61 children.add(child);62 }63 sb.setCharAt(i, cache);64 }65 66 return children;67 }68 69 private void dfs(Map<String, List<String>> graph, final String word, final String endWord,70 List<String> path, List<List<String>> ans) {71 if (word.equals(endWord)) {72 ans.add(new ArrayList<>(path));73 return;74 }75 if (!graph.containsKey(word))76 return;77 78 for (final String child : graph.get(word)) {79 path.add(child);80 dfs(graph, child, endWord, path, ans);81 path.remove(path.size() - 1);82 }83 }84}85