Link: https://oj.leetcode.com/problems/word-ladder/
My thought: 1 How to build find a transformation? 2 How to make sure that this transformation is shortest?
Approach:
BFS. Each String is viewed as a node. If two Strings only have a letter difference, then there is an edge between them. The shortest transformation then becomes finding the shortest path in this graph.
(Figure: http://www.programcreek.com/2012/12/leetcode-word-ladder/)
Time: If we assume that String has length L. Then Time = O(min(26^L, size(dict)). When words in dict can have different length other than L.
public class Solution {
public int ladderLength(String start, String end, Set<String> dict) {
if(start == null || end == null || start.length()==0 ||end.length() ==0 || start.length()!= end.length()){
return 0;
}
LinkedList<String> queue = new LinkedList<String>();
HashSet<String> visited = new HashSet<String>();
queue.add(start);
visited.add(start);
int level = 1;
int lastNum = 1;//num of nodes in last level
int curNum = 0;//num of nodes in current level
while(!queue.isEmpty()){
String cur = queue.poll();
lastNum--;
//change one letter in cur
for(int i = 0; i < cur.length(); i++){
char[] charCur = cur.toCharArray();
for(char c = 'a'; c <='z'; c++){//for each adjacent String of cur (those only need to change one letter)
charCur[i] = c;
String nCur = new String(charCur);
if(nCur.equals(end)){//only one step from start to end
return level+1;
}
if(dict.contains(nCur) && !visited.contains(nCur)){
curNum++;
visited.add(nCur);
queue.add(nCur);
}
}
}
if(lastNum == 0){
lastNum = curNum;
curNum = 0;
level++;
}
}
return 0;
}
}
Note:
1 We cannot put this before the for loop. Its because when charCur is modified, cur will be modified accordingly.char[] charCur = cur.toCharArray();
2 To optimize it, We can add "dict.remove(nCur);" in if(dict.contains(nCur) && !visited.contains(nCur)){
http://blog.csdn.net/zxzxy1988/article/details/8591890
But we cannot do this optimization in Word Ladder II.
"(1)在本层能遍历到该元素。也就是说,我们到达这个元素有两条路径,而且它们都是最短路径。
比如hot->hog->dog->dig和hot->dot->dog->dig,那么在第一次遍历距离hot为1的元素时,我们找到了hog和dot。对hog遍历时,我们找到了dog,并且将其从字典中删除。那么在遍历距离dot为1的元素时,我们实际上是找不到dog的,因为已经被删除了。对于本题来说,是没有什么影响的,因为到dog距离都是3,到dig距离都是4。
(2)在更下层我们才能够遍历到该元素。比如hot->dot->dog->dig和hot->hat->dat->dag->dog->dig,如果第一次我们找到了dog并且将其删除,那么第二次我们实际上是找不到这个元素的。这样对于本题来说,没有任何影响。"
第二遍:@8.25.2014
我写的:框架基本正确。但是要记得BFS需要设两个变量记录当前层和下一层的节点数
public class Solution {
public int ladderLength(String start, String end, Set<String> dict) {
//BFS, each level stores all strings with one-char difference with the string on the above level
Queue<String> queue = new Queue<String>();
queue.add(start);
int level = 0;
while(!queue.isEmpty()){
String str = queue.poll();
char[] strArr = str.toCharArray();
for(int i = 0; i < strArr.length; i++){
for(char c = 'a'; c <='z'; c++){
if(c == strArr[i]) continue;
else{
strArr[i] = c;
String trans = new String(strArr);
if(dict.contains(trans)){
if(trans.equals(end)){
return level;
}
queue.add(trans);
}
}
}
}
level++;
}
}
}