Given two words (start and end), and a dictionary, find the length of shortest transformation sequence 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"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
Breadth first search. But the following solution will cause overflow if the dictionary is big.
public class Solution {
public int ladderLength(String start, String end, Set<String> dict) {
if (start == null || start.length() == 0 || end == null || end.length() == 0) {
return 0;
}
Queue<String> queue = new LinkedList<String>();
HashSet<String> visited = new HashSet<String>();
queue.offer(start);
int count = 2;
int lastNum = 1;
int currNum = 0;
while (!queue.isEmpty()) {
String cur = queue.poll();
lastNum--;
if (isValid(cur, end)) {
return count;
}
for (String s : dict) {
if (isValid(s, cur) && !visited.contains(s)) {
currNum++;
queue.offer(s);
visited.add(s);
}
}
if (lastNum == 0) {
lastNum = currNum;
currNum = 0;
count++;
}
}
return 0;
}
private boolean isValid(String word1, String word2) {
int changed = 0;
for (int i = 0; i < word1.length(); i++) {
if (word1.charAt(i) != word2.charAt(i)) changed++;
}
return changed == 1 ? true : false;
}
}
Instead of search in the dictionary, search for all other 25 alphabets. Time complexity O(min(26 * length of word, size of dict).
public class Solution {
public int ladderLength(String start, String end, Set<String> dict) {
if (start == null || start.length() == 0 || end == null || end.length() == 0) {
return 0;
}
Queue<String> queue = new LinkedList<String>();
HashSet<String> visited = new HashSet<String>();
int count = 2;
int lastNum = 1;
int currNum = 0;
queue.offer(start);
visited.add(start);
while (!queue.isEmpty()) {
String cur = queue.poll();
lastNum--;
for (int i = 0; i < cur.length(); i++) {
char[] currChar = cur.toCharArray();
for (char c = 'a'; c <= 'z'; c++) {
currChar[i] = c;
String s = new String(currChar);
if (s.equals(end)) {
return count;
}
if (dict.contains(s) && !visited.contains(s)) {
currNum++;
queue.offer(s);
visited.add(s);
}
}
}
if (lastNum == 0) {
lastNum = currNum;
currNum = 0;
count++;
}
}
return 0;
}
}