public class Solution {
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
if (beginWord.equals(endWord)) { return 1; }
if (isLinked(beginWord, endWord)) { return 2; }
wordList.remove(beginWord);
wordList.remove(endWord);
Set<String> frontier = new HashSet<>();
frontier.add(beginWord);
Set<String> opposite = new HashSet<>();
opposite.add(endWord);
int pathLength = 2;
while (!frontier.isEmpty() && !opposite.isEmpty()) {
pathLength++;
Set<String> nexts = new HashSet<>();
for (String cur : frontier) for (String word : wordList) {
if (isLinked(cur, word)) {
// if already linked to the right part, just win
for (String r : opposite) if (isLinked(word, r)) {
return pathLength;
}
nexts.add(word);
}
}
for (String word : nexts) { wordList.remove(word); }
frontier = nexts;
if (opposite.size() < frontier.size()) {
Set<String> tmp = frontier;
frontier = opposite;
opposite = tmp;
}
}
return 0;
}
private boolean isLinked(String a, String b) {
int len = a.length();
int distance = 0;
for (int i = 0; i < len; i++) if (a.charAt(i) != b.charAt(i)) {
if (++distance > 1) return false;
}
return true;
}
}