[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:
- Only one letter can be changed at a time
- 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即可。