Word Ladder I & II

著名 gay 题,时间复杂度爆炸的典范,也是目前我知道的 leetcode 题里唯一一道非常适合使用 bi-directional bfs 的问题。

比较独特的是这题不是 DFS + Backtracking,主要原因在于我们要确保 “路线最短” ,这个更适合用 BFS 解决,两层字典首次相交的地方一定是最短路线。

public class Solution {
    public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
        if(beginWord.length() != endWord.length()) return 0;
        if(wordList == null || wordList.size() == 0) return 0;
        if(beginWord.equals(endWord)) return 2;

        HashSet<String> beginSet = new HashSet<String>();
        HashSet<String> endSet = new HashSet<String>();

        beginSet.add(beginWord);
        endSet.add(endWord);

        wordList.remove(beginWord);
        wordList.remove(endWord);

        return bfs(2, beginSet, endSet, wordList);
    }

    private int bfs(int steps, Set<String> beginSet, Set<String> endSet, Set<String> wordSet){

        HashSet<String> nextLevel = new HashSet<String>();

        for(String beginWord : beginSet){
            char[] charArray = beginWord.toCharArray();
            for(int pos = 0; pos < charArray.length; pos++){
                for(char chr = 'a'; chr <= 'z'; chr++){
                    charArray[pos] = chr;
                    String str = String.valueOf(charArray);
                    if(endSet.contains(str)) return steps;

                    if(wordSet.contains(str)){
                        nextLevel.add(str);
                        wordSet.remove(str);
                    }
                }
                charArray = beginWord.toCharArray();
            }
        }
        if(nextLevel.size() == 0) return 0;

        if(endSet.size() < nextLevel.size()){
            return bfs(steps + 1, endSet, nextLevel, wordSet);
        } else {
            return bfs(steps + 1, nextLevel, endSet, wordSet);
        }
    }
}

除了递归之外,还可以用迭代。反正迭代的 BFS 好写。

LeetCode 著名 gay 题的加强版,烦人程度更上一层楼。。。当要返回所有 path 的时候,细节处理就更多了。其实这题和 Longest Increasing Subsequence 的 follow-up ,返回所有 LIS 有相通的地方,都是维护一个 Directed Graph 关系并且从某一个终点进行 dfs 返回所有 valid path.

这题的最终解法是一个 Bi-directional BFS 与 DFS 的结合,因为 bfs 过程中起点终点会调换,为了保证 path 的正确性要 keep track of direction.

有向图找最短距离用 BFS

有向图返回所有路径用 DFS

HashMap 中 value 是 List 可以直接map.get(key).add(value);

Last updated