Leetcode 126. Word Ladder II

Given two words (beginWord and endWord), and a dictionary’s word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,
Given:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,”dot”,”dog”,”lot”,”log”,”cog”]
Return
[
[“hit”,”hot”,”dot”,”dog”,”cog”],
[“hit”,”hot”,”lot”,”log”,”cog”]
]

题意:127题的followup,要求不单是求最少变换次数,还要返回所有符合最短变换次数的具体变换。

思路:
先用bfs找寻最短路径,同时为每个单词标上它的最短等级;
然后用dfs搜索所有最短路径,搜索的条件就是下一个单词的最短等级等于当前单词最短等级+1.

public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
    HashSet<String> dict = new HashSet<>(wordList);
    dict.add(beginWord);

    HashMap<String, Integer> depth = new HashMap<>();
    HashMap<String, List<String>> neighbours = new HashMap<>();
    for (String word : wordList) {
        neighbours.put(word, new ArrayList<>());
    }
    neighbours.put(beginWord, new ArrayList<>());

    List<List<String>> res = new ArrayList<>();
    List<String> subres = new ArrayList<>();
    bfs(beginWord, endWord, dict, depth, neighbours);
    dfs(beginWord, endWord, dict, neighbours, depth, subres, res);

    return res;
}

public void bfs(String beginWord, String endWord, HashSet<String> dict, HashMap<String, Integer> depth, HashMap<String, List<String>> neighbours) {
    Queue<String> q = new LinkedList<>();
    q.add(beginWord);
    depth.put(beginWord, 0);

    while (!q.isEmpty()) {
        int size = q.size();
        boolean found = false;
        for (int i = 0; i < size; i++) {
            String cur = q.poll();
            int curDistance = depth.get(cur);
            List<String> nextWords = getNextWords(cur, dict);
            for (String nextWord : nextWords) {
                neighbours.get(cur).add(nextWord);
                if (!depth.containsKey(nextWord)) {
                    depth.put(nextWord, curDistance + 1);
                    if (endWord.equals(nextWord)) {
                        found = true;
                    } else {
                        q.offer(nextWord);
                    }
                }
            }
        }
        if (found) {
            break;
        }
    }
}

//bug 这里不能过滤掉depth中已经有的word,否则会导致某些词的neighbours有缺失

// public List<String> getNextWords(String word, HashSet<String> dict, HashMap<String, Integer> depth) {
public List<String> getNextWords(String word, HashSet<String> dict) {
List<String> list = new ArrayList<>();
char[] chars = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
for (char c = ‘a’; c <= ‘z’; c++) {
if (chars[i] == c) {
continue;
}
char origin = chars[i];
chars[i] = c;
String nextWord = new String(chars);
// if (dict.contains(nextWord) && !depth.containsKey(nextWord)) {
if (dict.contains(nextWord)) {
list.add(nextWord);
}
chars[i] = origin;
}
}

    return list;
}

private void dfs(String cur, String end, Set<String> dict, HashMap<String, List<String>> nodeNeighbors, HashMap<String, Integer> distance, List<String> solution, List<List<String>> res) {
    solution.add(cur);
    if (end.equals(cur)) {
        res.add(new ArrayList<>(solution));
    } else {
        List<String> neighbours = nodeNeighbors.get(cur);
        for (String next : nodeNeighbors.get(cur)) {
            if (distance.get(next) == distance.get(cur) + 1) {
                dfs(next, end, dict, nodeNeighbors, distance, solution, res);
            }
        }
    }
    solution.remove(solution.size() - 1);
}
    原文作者:ShutLove
    原文地址: https://www.jianshu.com/p/52ad9b25a1f8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞