[leetcode-126]Word Ladder II(java)

来源:互联网 发布:淘宝店铺人群消费层级 编辑:程序博客网 时间:2024/05/20 11:26

问题描述:这里写链接内容

分析:这道题首先要找到最短路径,最短路径是采用BFS方法,之前侯大神给我讲的时候说,为什么BFS找到的节点是最短的,因为BFS搜索过程是类似于波浪型的,一层一层荡出去,这样只要找到了结束点,这个店就一定是最短路径。
但是这道题要求把路径找出来,所以,在BFS过程中还需要记录中间路径,(实际上是构造一棵树),然后在BFS结束之后再进行DFS搜索。这里的一个trick是,在BFS的过程中由后向前找。这样可以避免很多无效的分支。所以需要一个map维护string和它的上一层之间的对应关系。

此外,BFS的搜索过程中并非简单地使用队列的结构,因为每一层与每一层之间要相互隔离,因为很可能上一层之间还有相互指向的支,那么这些支是无效的,应该予以排除。

此外,还要注意什么时候退出循环,当找到end节点之后,并把那一层搜索完之后再退出。
总之这道题很恶心!
代码如下:656ms

public class Solution {  class Node {    String word;    int level;    public Node(String word, int level) {        this.word = word;        this.level = level;    }}    private String end;    private List<List<String>> res;    private Map<String, List<String>> maps;    public List<List<String>> findLadders(String start, String end,                                                    Set<String> dict) {        res = new ArrayList<>();        // unvisited words set        dict.add(end);        dict.remove(start);        // used to record the map info of <word : the words of next level>        maps = new HashMap<>();        for (String e : dict) {            maps.put(e, new ArrayList<>());        }        // BFS to search from the end to start        Queue<Node> queue = new LinkedList<Node>();        queue.add(new Node(start, 0));        boolean found = false;        int finalLevel = Integer.MAX_VALUE;        int currentLevel = 0;        Set<String> visitedWordsInThisLevel = new HashSet<>();        while (!queue.isEmpty()) {            Node node = queue.poll();            String word = node.word;            int level  = node.level;            if (level > finalLevel) {                break;            }            if (level > currentLevel) {                dict.removeAll(visitedWordsInThisLevel);                visitedWordsInThisLevel.clear();            }            currentLevel = level;            char[] wordCharArray = word.toCharArray();            for (int i = 0; i < word.length(); ++i) {                char originalChar = wordCharArray[i];                boolean foundInThisCycle = false;                for (char c = 'a'; c <= 'z'; ++c) {                    wordCharArray[i] = c;                    String newWord = new String(wordCharArray);                    if (c != originalChar && dict.contains(newWord)) {                        maps.get(newWord).add(word);                        if (newWord.equals(end)) {                            found = true;                            finalLevel = currentLevel;                            foundInThisCycle = true;                            break;                        }                        if (visitedWordsInThisLevel.add(newWord)) {                            queue.add(new Node(newWord, currentLevel + 1));                        }                    }                }                if (foundInThisCycle) {                    break;                }                wordCharArray[i] = originalChar;            }        }        if(found){            List<String> tmplist = new LinkedList<>();            generatePath(end,start,tmplist);        }        return res;    }    private void generatePath(String start,String end,List<String> list){        if(start.equals(end)){            List<String> tmplist = new LinkedList<>(list);            tmplist.add(end);            Collections.reverse(tmplist);            res.add(tmplist);            return;        }        list.add(start);        List<String> tmplist = maps.get(start);        for(String e:tmplist)            generatePath(e,end,list);        list.remove(list.size()-1);    }}
0 0
原创粉丝点击