码迷,mamicode.com
首页 > 编程语言 > 详细

[LeetCode-JAVA] Word Ladder II

时间:2015-06-14 15:01:43      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

题目:

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

思路:先建立dict的邻接链表,例子中的结果如下:

hit : [hot]
cog : [dog, log]
hot : [hit, lot, dot]
lot : [hot, log, dot]
dog : [cog, log, dot]
log : [cog, lot, dog]
dot : [lot, hot, dog]

在Word LadderI的基础上,由于要重新构建结果集,因此要自己创建一个Node类,保存每一个节点的上一个节点,这样在找到最短结果的时候,以此找到该节点的上一个节点,加入链表即可。

需要注意的几点:

(1)构建邻接链表前,需要把start和end加入,这样才能找到结果。

(2)构建邻接链表的时候,对于每一个单词,一定要在每一次替换char后,再将其恢复,以便进行下一次判断。

(3)每一层的queue用一个num来记录此层的Node个数,只要是找到一个,就证明这一层即为最短路径,设标志位为true,将该层循环之后,结束循环。

(4)循环的过程中,需要判断节点是否已经被判断过,创建一个Set用于记录所有判断过的节点。

代码:

public class Solution {
    private class Node{
        public Node pre;
        public String val;
        public Node(Node p, String s){
            pre = p;
            val = s;
        }
    }
    public List<List<String>> findLadders(String start, String end, Set<String> dict) {
        dict.add(start);
        dict.add(end); //注意(1)
        Map<String, Set<String>> neighbours = calNeighbours(dict);
        
        List<List<String>> req = new ArrayList<List<String>>();
        
        LinkedList<Node> queue = new LinkedList<Node>();
        queue.offer(new Node(null, start)); //开始节点的前一个为null
        
        Set<String> visited = new HashSet<String>(); //注意(4)
        boolean flag = false; //注意(3)
        while(!queue.isEmpty() || visited.size() == dict.size()){
            int num = queue.size();
            for(int i = 0 ; i < num ; i++){
                Node n = queue.poll();
                if(end.equals(n.val)){
                    findPath(n, req);
                    flag = true; //注意(3)
                }else{
                    Set<String> temp = neighbours.get(n.val);
                    if(temp == null || temp.size() == 0)
                        continue;
                    else{
                        for(String s : temp){
                            if(!visited.contains(s)){ //注意(4)
                                queue.offer(new Node(n, s));
                            }
                        }
                    }
                }
                visited.add(n.val);//注意(4)
            }
            if(flag)
                break;
        }
        if(!flag) // 如果flag为false,证明无解
            return new ArrayList<List<String>>();
        return req;
    }
    
    private void findPath(Node n, List<List<String>> req) {
        // TODO Auto-generated method stub
        List<String> temp = new ArrayList<String>();
        while(n != null){
            temp.add(0, n.val);
            n = n.pre;
        }
        req.add(temp);
    }
    public Map<String, Set<String>> calNeighbours(Set<String> dict) {
        Map<String, Set<String>> neighbours = new HashMap<String, Set<String>>();
        
        for(String str : dict){
            int len = str.length();
            char[] chars = str.toCharArray();
            
            for(int i = 0 ; i < len ; i++){
                char old = chars[i]; //注意(2)
                for(char c = ‘a‘ ; c <= ‘z‘ ; c++){
                    if(c == chars[i])
                        continue;
                    chars[i] = c;
                    String newstr = new String(chars);
                    
                    if(dict.contains(newstr)) {
                        Set<String> set = neighbours.get(str);
                        if(set != null)
                            set.add(newstr);
                        else{
                            Set<String> newset = new HashSet<String>();
                            newset.add(newstr);
                            neighbours.put(str, newset);
                        }
                    }
                    chars[i] = old ; //注意(2)引用型变量 每一次用完要还原 
                } // end fot c
            } // end for len
        } // end for str

        return neighbours;
    }
}

AC时间为 1120ms左右,因此还有很大的改进空间,继续新的思路。

[LeetCode-JAVA] Word Ladder II

标签:

原文地址:http://www.cnblogs.com/TinyBobo/p/4575009.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!