robturtle
10/17/2016 - 9:40 PM

WordLadder.java

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;
    }
}