Word Ladder II Feb 11
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) fromstart toend, 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.
[思路]
同word ladder I 一样, 但是为了能够trace back. 建立一个树, 树的节点有一个父指针. 同时, 删除字典中的word时, 不能像word ladder I中,立刻删, 因为同一个word有可能再本层中被别的branch使用, 所以, 统一在每层结束时删除. 用特殊字符"#", 标示每一层结束.
[CODE]
public class Solution {
public List<List<String>> findLadders(String start, String end, Set<String> dict) {
Queue<Node> que = new LinkedList<Node>();
List<List<String>> res = new ArrayList<List<String>>();
Set<String> rmList = new HashSet<String>();
dict.add(end);
boolean flag = false;
dict.remove(start);
que.add( new Node(start, null) );
que.add(new Node("#",null));
while(!que.isEmpty() ) {
Node n = que.remove();
if(n.val.equals("#") ) {
if(flag || que.isEmpty()) return res;
dict.removeAll(rmList);
rmList.clear();
que.add(new Node("#", null));
continue;
}
if(n.val.equals(end) ) {
flag = true;
List<String> cur = getBranch(n);
res.add(cur);
}
List<Node> adjs = findAdjs(n, end, dict, rmList);
que.addAll(adjs);
}
return res;
}
private List<String> getBranch(Node n) {
List<String> branch = new ArrayList<String>();
while(n!=null) {
branch.add(n.val);
n = n.parent;
}
Collections.reverse(branch);
return branch;
}
private List<Node> findAdjs(Node n, String end, Set<String> dict, Set<String> rmList) {
String s = n.val;
List<Node> adjs = new ArrayList<Node>();
for(int i=0; i<s.length(); i++) {
StringBuilder sb = new StringBuilder(s);
for(char c='a'; c<'z'; c++) {
sb.setCharAt(i, c);
String sbs = sb.toString();
if(dict.contains(sbs)) {
adjs.add(new Node(sbs, n));
if(!sbs.equals(end)) rmList.add(sbs);
}
}
}
return adjs;
}
}
class Node{
String val;
Node parent;
public Node(String val, Node parent) {
this.val = val;
this.parent = parent;
}
}