Word Ladder II leetcode java

题目

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"]
  ]

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

 

题解

答案是http://www.1point3acres.com/bbs/thread-51646-1-1.html 上面 iostreamin写的。

我就直接贴过来就好,这道题多读读代码看明白。

 

 代码:

 

  1     public ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict) {  
  2           
  3         HashMap<String, HashSet<String>> neighbours =  new HashMap<String, HashSet<String>>();  
  4           
  5         dict.add(start);  
  6         dict.add(end);  
  7           
  8          //  init adjacent graph          
  9           for(String str : dict){  
 10             calcNeighbours(neighbours, str, dict);  
 11         }  
 12           
 13         ArrayList<ArrayList<String>> result =  new ArrayList<ArrayList<String>>();  
 14           
 15          //  BFS search queue  
 16          LinkedList<Node> queue =  new LinkedList<Node>();  
 17         queue.add( new Node( null, start, 1));  // the root has not parent and its level == 1 
 18            
 19           //  BFS level  
 20           int previousLevel = 0;  
 21           
 22          //  mark which nodes have been visited, to break infinite loop  
 23          HashMap<String, Integer> visited =  new HashMap<String, Integer>();   
 24          while(!queue.isEmpty()){  
 25             Node n = queue.pollFirst();              
 26              if(end.equals(n.str)){   
 27                  //  fine one path, check its length, if longer than previous path it's valid  
 28                   //  otherwise all possible short path have been found, should stop  
 29                   if(previousLevel == 0 || n.level == previousLevel){  
 30                     previousLevel = n.level;  
 31                     findPath(n, result);                      
 32                 } else {  
 33                      //  all path with length *previousLevel* have been found  
 34                       break;  
 35                 }                  
 36             } else {  
 37                 HashSet<String> set = neighbours.get(n.str);                   
 38                   
 39                  if(set ==  null || set.isEmpty())  continue;  
 40                  //  note: I'm not using simple for(String s: set) here. This is to avoid hashset's  
 41                   //  current modification exception.  
 42                  ArrayList<String> toRemove =  new ArrayList<String>();  
 43                  for (String s : set) {  
 44                       
 45                      //  if s has been visited before at a smaller level, there is already a shorter   
 46                       //  path from start to s thus we should ignore s so as to break infinite loop; if   
 47                       //  on the same level, we still need to put it into queue.  
 48                       if(visited.containsKey(s)){  
 49                         Integer occurLevel = visited.get(s);  
 50                          if(n.level+1 > occurLevel){  
 51                             neighbours.get(s).remove(n.str);  
 52                             toRemove.add(s);  
 53                              continue;  
 54                         }  
 55                     }  
 56                     visited.put(s,  n.level+1);  
 57                     queue.add( new Node(n, s, n.level + 1));  
 58                      if(neighbours.containsKey(s))  
 59                         neighbours.get(s).remove(n.str);  
 60                 }  
 61                  for(String s: toRemove){  
 62                     set.remove(s);  
 63                 }  
 64             }  
 65         }  
 66   
 67          return result;  
 68     }  
 69       
 70      public  void findPath(Node n, ArrayList<ArrayList<String>> result){  
 71         ArrayList<String> path =  new ArrayList<String>();  
 72         Node p = n;  
 73          while(p !=  null){  
 74             path.add(0, p.str);  
 75             p = p.parent;   
 76         }  
 77         result.add(path);  
 78     }  
 79   
 80      /*  
 81       * complexity: O(26*str.length*dict.size)=O(L*N) 
 82        */  
 83      void calcNeighbours(HashMap<String, HashSet<String>> neighbours, String str, HashSet<String> dict) {  
 84          int length = str.length();  
 85          char [] chars = str.toCharArray();  
 86          for ( int i = 0; i < length; i++) {  
 87               
 88              char old = chars[i];   
 89              for ( char c = 'a'; c <= 'z'; c++) {  
 90   
 91                  if (c == old)   continue;  
 92                 chars[i] = c;  
 93                 String newstr =  new String(chars);                  
 94                   
 95                  if (dict.contains(newstr)) {  
 96                     HashSet<String> set = neighbours.get(str);  
 97                      if (set !=  null) {  
 98                         set.add(newstr);  
 99                     }  else {  
100                         HashSet<String> newset =  new HashSet<String>();  
101                         newset.add(newstr);  
102                         neighbours.put(str, newset);  
103                     }  
104                 }                  
105             }  
106             chars[i] = old;  
107         }  
108     }  
109       
110      private  class Node {  
111          public Node parent;   // previous node
112           public String str;  
113          public  int level;  
114          public Node(Node p, String s,  int l){  
115             parent = p;  
116             str = s;  
117             level = l;  
118         }  
119     } 

 Reference:http://www.1point3acres.com/bbs/thread-51646-1-1.html

你可能感兴趣的:(LeetCode)