A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:
Every adjacent pair of words differs by a single letter.
Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.
sk == endWord
Given two words, beginWord and endWord, and a dictionary wordList, return the number of words in the shortest transformation sequence frombeginWordtoendWord, or0if no such sequence exists.
Example 1:
**Input:** beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
**Output:** 5
**Explanation:** One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> cog", which is 5 words long.
Example 2:
**Input:** beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
**Output:** 0
**Explanation:** The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.
Constraints:
1 <= beginWord.length <= 10
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord, endWord, and wordList[i] consist of lowercase English letters.
beginWord != endWord
All the words in wordList are unique.
ac1: Graph + BFS
12/22/2017
very time consuming in building the graph Buiding the graph is awaste of time here.
classSolution {publicintladderLength(String beginWord,String endWord,List<String> wordList) {wordList.add(beginWord);int begin =wordList.size() -1;int end =-1;// Build graph, iterate wordlist get edges.List<List<Integer>> adjList =newArrayList<List<Integer>>();for (int i =0; i <wordList.size(); i++) {adjList.add(newArrayList<Integer>()); }for (int i =0; i <wordList.size(); i++) {if (wordList.get(i).equals(endWord)) end = i;for (int j = i +1; j <wordList.size(); j++) {if (isConnected(wordList.get(i),wordList.get(j))) {adjList.get(i).add(j);adjList.get(j).add(i); } } }// BFSint layer =0;Queue<Integer> q =newLinkedList<Integer>();boolean[] visited =newboolean[wordList.size()];q.offer(begin);while (!q.isEmpty()) {int len =q.size(); layer++;for (int i =0; i < len; i++) {int head =q.poll(); visited[head] =true;for (int next :adjList.get(head)) {if (visited[next]) continue;if (next == end) return layer+1;q.offer(next); } } }// can't findreturn0; }privatebooleanisConnected(String s1,String s2) {int diff =0;for (int i =0; i <s1.length(); i++) {if (s1.charAt(i) !=s2.charAt(i)) diff++; }return diff ==1; }}
ac2: BFS
Simpler and much faster. iterate through word is much faster iterate wordList.
classSolution {publicintladderLength(String beginWord,String endWord,List<String> wordList) {Set<String> wordSet =newHashSet<String>(wordList);int layer =0;Queue<String> q =newLinkedList<String>();q.offer(beginWord);while (!q.isEmpty()) {int len =q.size(); layer++;for (int i =0; i < len; i++) {String head =q.poll();// get head's adjcent words in dictfor (int l =0; l <head.length(); l++) {for (char c ='a'; c <='z'; c++) { chars[l] = c;String headDiff =String.valueOf(chars);if (wordSet.contains(headDiff)){if (headDiff.equals(endWord)) return layer +1; // Find endword, return.q.offer(headDiff);wordSet.remove(headDiff); } } } } }return0; }}
ac3: bidirectional BFS
classSolution {publicintladderLength(String beginWord,String endWord,List<String> wordList) {// edge casesif (wordList ==null||wordList.size() ==0) return0;Set<String> wordSet =newHashSet<>(wordList);if (!wordSet.contains(endWord)) return0;Set<String> visited =newHashSet<>();Set<String> beginSet =newHashSet<>();beginSet.add(beginWord);Set<String> endSet =newHashSet<>();endSet.add(endWord);int len =0;while (!beginSet.isEmpty() &&!endSet.isEmpty()) {if (beginSet.size() >endSet.size()) {Set<String> tmp = beginSet; beginSet = endSet; endSet = tmp; } len++;Set<String> tmpSet =newHashSet<>();for(String w : beginSet) {char[] chars =w.toCharArray();for (int i =0; i <chars.length; i++) {char old = chars[i];for (char c ='a'; c <='z'; c++) { chars[i] = c;String newWord =String.valueOf(chars);if (wordSet.contains(newWord)) {if (endSet.contains(newWord)) return len +1;if (!visited.contains(newWord)) {tmpSet.add(newWord);visited.add(newWord); } } } chars[i] = old; } } beginSet = tmpSet; }return0; // can't find }}/*BFSQueue<String> qtransform word 1 letter a step, lookup in dict, if contains, add to queue, if == endword returnreturn 0;*/