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.
找到所有最短变化路径
墨迹好久好久,怎么写怎么超时。。以后还得继续琢磨
public class Solution {
static class Node {
String word;
ArrayList<Node> before;
Node(String word) {
this.word = word;
this.before = new ArrayList<Node>();
}
}
public ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict) {
ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();
char[] chs = new char[start.length()];
ArrayList<Node> now = new ArrayList<Node>(), next = null;
now.add(new Node(start));
dict.add(end);
dict.remove(start);
int length = start.length(), deep = 0;
while (now.size() > 0 && dict.contains(end)) {
deep++;
next = new ArrayList<Node>();
HashMap<String, Node> nextMap = new HashMap<String, Node>();
for (Node i : now) {
i.word.getChars(0, length, chs, 0);
for (int j = 0; j < length; j++) {
char tmp = chs[j];
for (char k = 'a'; k <= 'z'; k++) {
chs[j] = k;
String str = new String(chs);
if (!dict.contains(str)) {
continue;
}
Node node = nextMap.get(str);
if (node == null) {
node = new Node(str);
nextMap.put(str, node);
next.add(node);
}
node.before.add(i);
}
chs[j] = tmp;
}
}
for (String key : nextMap.keySet()) {
dict.remove(key);
}
now = next;
}
if (dict.contains(end)) {
return ret;
}
Node root = null;
for (Node i : now) {
if (i.word.equals(end)) {
root = i;
break;
}
}
Node[] nodes = new Node[deep + 2];
nodes[deep] = new Node(start);
dfs(root, ret, nodes, 0, deep);
return ret;
}
private void dfs(Node root, ArrayList<ArrayList<String>> ret, Node[] nodes, int nodeIndex,
int deep) {
if (nodeIndex == deep) {
ArrayList<String> tmp = new ArrayList<String>(deep);
for (int i = nodeIndex; i >= 0; i--) {
tmp.add(nodes[i].word);
}
ret.add(tmp);
} else {
nodes[nodeIndex] = root;
for (Node b : root.before) {
dfs(b, ret, nodes, nodeIndex + 1, deep);
}
}
}
}