Question
Given two words (beginWord and endWord), and a dictionary’s word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,

Given:
beginWord = ​​`​"hit"​`​​
endWord = ​​`​"cog"​`​​
wordList = ​​`​["hot","dot","dog","lot","log"]​`​​
As one shortest transformation is ​​`​"hit" -> "hot" -> "dot" -> "dog" -> "cog"​`​​,
return its length ​​`​5​`​.

Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.

1、BFS

【复杂度】

【思路】

【注意】
base case为队列​​`​q.size()==0​`​​而不是​`​wordList.size()==0​`​​，因为并不是​`​wordList​`​中所有的单词都会被BFS到。

【代码】

`public class Solution {    public int ladderLength(String beginWord, String endWord, Set<String> wordList) {        //require        Queue<String> q=new LinkedList<>();        q.offer(beginWord);        //invariant        return bfs(2,q,endWord,wordList);    }    private int bfs(int length,Queue<String> q,String endWord, Set<String> wordList){        //base case        if(q.size()==0){            return 0;        }        Queue<String> nextQ=new LinkedList<>();        while(!q.isEmpty()){            String word=q.poll();            char[] cArray = word.toCharArray();            for(int i=0;i<word.length();i++){                for(char c='a';c<='z';c++){                    char ci=cArray[i];                    cArray[i]=c;                    String tmp=new String(cArray);                    //包括word本身也要进行检查                    if(tmp.equals(endWord))                        return length;                    else if(wordList.contains(tmp)){                        nextQ.offer(tmp);                        wordList.remove(tmp);                    }                    cArray[i]=ci;                }            }        }        return bfs(length+1,nextQ,endWord,wordList);    }}`

2、Two End BFS

【复杂度】

【思路】

`String word=q.poll();char[] cArray = word.toCharArray();for(int i=0;i<word.length();i++){    for(char c='a';c<='z';c++){        char ci=cArray[i];        cArray[i]=c;        String tmp=new String(cArray);        if(tmp.equals(endWord))            return length;        else if(wordList.contains(tmp)){            nextQ.offer(tmp);            wordList.remove(tmp);        }        cArray[i]=ci;    }}`

【代码】

`public class Solution {    public Set<String> getNeighbors(String cur, Set<String> dict) {        Set<String> neighbors = new HashSet<>();        char[] cArray = cur.toCharArray();        for (int i = 0; i < cArray.length; ++i) {            char ci= cArray[i];            for (char c = 'a'; c <= 'z'; ++c) {                if (c == ci) {                    continue;                }                cArray[i] = c;                String s = new String(cArray);                if (dict.contains(s)) {                    neighbors.add(s);                }            }            cArray[i] = ci;        }        return neighbors;    }    public int ladderLength(String beginWord, String endWord, Set<String> wordList) {        Set<String> s1 = new HashSet<>();        Set<String> s2 = new HashSet<>();        s1.add(beginWord);        s2.add(endWord);        // choose the set has the smaller size        boolean isS1 = s1.size() < s2.size() ? true : false;        Set<String> ss = isS1 ? s1 : s2;        Set<String> ls = isS1 ? s2 : s1;        int res = 0;        while (!ss.isEmpty()){            ++res;            // remove for better performance and solve the visited problem            wordList.removeAll(ss);            // similar as queue.poll() in BFS            Set<String> ns = new HashSet<>();            for (String cur : ss) {                if (ls.contains(cur)) {                    return res;                }                for (String neighbor : getNeighbors(cur, wordList)) {                        ns.add(neighbor);                }            }            // choose the set has the smaller size            isS1 = ns.size() < ls.size() ? true : false;            ss = isS1 ? ns : ls;            ls = isS1 ? ls : ns;        }        return 0;    }}`

【附】

1. 本题对于beginWord与endWord相等的情况，length 可以等于​`​1​`​​也可以等于​`​2​`​。
2. 方法1是先对​`​word​`​​进行变形再检查是否等于​`​endWord​`​​（其中还包括​`​word​`​​自己），是一种映射方法；方法2是先检查​`​ss​`​​中的​`​cur​`​​是否包含于​`​ls​`​​，再变形​`​cur​`​，是一种集合方法。