My code:
public class Solution {
private class wordNode {
String s;
int step;
wordNode pre;
wordNode(String s, int step, wordNode pre) {
this.s = s;
this.step = step;
this.pre = pre;
}
}
public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
List<List<String>> ret = new ArrayList<List<String>>();
Queue<wordNode> q = new LinkedList<wordNode>();
q.offer(new wordNode(beginWord, 1, null));
Set<String> visited = new HashSet<String>();
Set<String> unvisited = wordList;
unvisited.add(endWord);
int prevStep = 0;
int minStep = 0;
while (!q.isEmpty()) {
wordNode node = q.poll();
int currStep = node.step;
if (node.s.equals(endWord)) {
if (minStep == 0) {
minStep = currStep;
}
if (currStep == minStep) {
List<String> path = new ArrayList<String>();
while (node != null) {
path.add(0, node.s);
node = node.pre;
}
ret.add(path);
}
continue;
}
if (prevStep < currStep) {
unvisited.removeAll(visited);
}
prevStep = currStep;
char[] arr = node.s.toCharArray();
for (int i = 0; i < arr.length; i++) {
for (char c = 'a'; c <= 'z'; c++) {
char temp = arr[i];
arr[i] = c;
String newWord = String.valueOf(arr);
if (unvisited.contains(newWord)) {
q.offer(new wordNode(newWord, currStep + 1, node));
visited.add(newWord);
}
arr[i] = temp;
}
}
}
return ret;
}
}
reference:
http://www.programcreek.com/2014/06/leetcode-word-ladder-ii-java/
Leetcode 最经典的一道题目,就这样被我糟蹋了。。
和 I 相比,有三个变化。
为了追踪。每个 wordNode 结点有一个 pre 指针,指向他的上一个结点。
minStep 用来保证,step最小的时候,才能把string插入 ret 中
I 中,当我发现一个string contained in set,就会把这个string从set中删去,因为我们只需要找到一个最优解。为了加快速度,就把他删了。这样其他排在后面的最优解,就不能继续遍历下去了。
但是这道题,我们要找到所有解。所以,只有当 当前 step全部遍历完后,才能把他们用到的string全部删除了。那如果以后其他的string需要用到他们呢?
这个时候,这些string的step已经不是最小了。
Anyway, Good luck, Richardo! -- 09/27/2016