[Leetcode] Word Ladder II

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.

 

Solution:

https://github.com/mengli/leetcode/blob/master/WordLadderII.java

1. 将start和end的值放入dict中,来统一进行操作。

2. candidates包含两个HashSet,相继当做current和previous数组。

3. prevMap包含了【current,list of previous nodes】这样的关系。

 1 package POJ;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import java.util.HashSet;
 6 import java.util.Map;
 7 
 8 public class Solution {
 9     public static void main(String[] args) {
10         Solution so = new Solution();
11         HashSet<String> dict=new HashSet<String>();
12         dict.add("hot");
13         dict.add("dog");
14         System.out.println(so.findLadders("hot", "dog",dict ));
15     }
16 
17     public ArrayList<ArrayList<String>> findLadders(String start, String end,
18             HashSet<String> dict) {
19         ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();
20         dict.add(start);
21         dict.add(end);
22         HashMap<String, ArrayList<String>> prevMap = new HashMap<String, ArrayList<String>>();
23         for (String s : dict) {
24             prevMap.put(s, new ArrayList<String>());
25         }
26         ArrayList<HashSet<String>> candidates = new ArrayList<HashSet<String>>();
27         candidates.add(new HashSet<String>());
28         candidates.add(new HashSet<String>());
29 
30         int current = 0;
31         int previous = 1;
32         candidates.get(current).add(start);
33         while (true) {
34             current = current == 0 ? 1 : 0;
35             previous = previous == 0 ? 1 : 0;
36 
37             candidates.get(current).clear();
38             for (String s : candidates.get(previous))
39                 dict.remove(s);
40             for (String wd : candidates.get(previous)) {
41                 for (int pos = 0; pos < wd.length(); ++pos) {
42                     StringBuilder word = new StringBuilder(wd);
43                     for (int i = 'a'; i <= 'z'; ++i) {
44                         if (wd.charAt(pos) == i)
45                             continue;
46                         word.setCharAt(pos, (char) i);
47                         if (dict.contains(word.toString())) {
48                             candidates.get(current).add(word.toString());
49                             prevMap.get(word.toString()).add(wd);
50                         }
51                     }
52                 }
53             }
54 
55             if (candidates.get(current).contains(end))
56                 break;
57             if (candidates.get(current).size() == 0)
58                 return ret;
59         }
60         ArrayList<String> al = new ArrayList<String>();
61         dfs(ret, al, end, prevMap);
62         return ret;
63     }
64 
65     private void dfs(ArrayList<ArrayList<String>> ret, ArrayList<String> path,
66             String word, HashMap<String, ArrayList<String>> prevMap) {
67         // TODO Auto-generated method stub
68         
69         if(prevMap.get(word).size()==0){
70             path.add(0,word);
71             ArrayList<String> curPath = new ArrayList<String>(path);
72             ret.add(curPath);
73             path.remove(0);
74             return;
75         }
76         
77         path.add(0, word);
78         for(String s: prevMap.get(word)){
79             dfs(ret, path, s, prevMap);
80         }
81         path.remove(0);
82     }
83 }

 

这里需要注意的是:

这种情况时,说明start和end之间没有路,直接返回空的ret即可。

 

posted @ 2014-10-13 16:10  Phoebe815  阅读(151)  评论(0编辑  收藏  举报