您的位置:首页 > 编程语言 > Java开发

[leetcode-126]Word Ladder II(java)

2015-09-04 22:03 591 查看
问题描述:这里写链接内容

分析:这道题首先要找到最短路径,最短路径是采用BFS方法,之前侯大神给我讲的时候说,为什么BFS找到的节点是最短的,因为BFS搜索过程是类似于波浪型的,一层一层荡出去,这样只要找到了结束点,这个店就一定是最短路径。

但是这道题要求把路径找出来,所以,在BFS过程中还需要记录中间路径,(实际上是构造一棵树),然后在BFS结束之后再进行DFS搜索。这里的一个trick是,在BFS的过程中由后向前找。这样可以避免很多无效的分支。所以需要一个map维护string和它的上一层之间的对应关系。

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

此外,还要注意什么时候退出循环,当找到end节点之后,并把那一层搜索完之后再退出。

总之这道题很恶心!

代码如下:656ms

[code]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);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: