题目:
Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformation sequence from beginWord to endWord, 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.
思路
这个问题可以转换成求最短路径的问题
因为这里每条边的长度都是1,所以,可以考虑采用BFS
需要根据转换关系,构造邻接矩阵来表示这个有向图吗?
没必要,这本身就是相当耗时的操作,可以在遍历的过程查找相邻的节点==也就是位于同一层的所有节点!那么怎么判断,当前符合条件的节点是否已经遍历过了?
设置一个Set visited 来存储遍历过的节点怎么找到与当前节点相邻的所有节点?
因为相邻节点只有一个字符不同,而且这个字符在a-z之间,所以可以对该节点的每个字符
从a-z设一遍,看dict集合中是否存在这个字符,或是否等于end; 这样时间复杂度为O(26*strLength);
另一种方法,就是拿这个字符串与集合中的每个字符串比较一次,每比较一次时间复杂度O(strLength),
字符串个数n , 假设比较之前会查看是否遍历过,总的时间度应当为(n-1 + n - 2 + .. + 1)strLength = O(n^2strLength)BFS怎么判断一层已经遍历完?
在每一层后面加一个标志位null (队列中), 如果遍历到null,说明这一层已经结束 ==> level + 1;
public int ladderLength(String start, String end, Set<String> dict) {
// Use queue to help BFS
Queue<String> queue = new LinkedList<String>();
queue.add(start);
queue.add(null);
// Mark visited word
Set<String> visited = new HashSet<String>();
visited.add(start);
int level = 1;
while (!queue.isEmpty()) {
String str = queue.poll();
if (str != null) {
// Modify str's each character (so word distance is 1)
// 这一步就取得了下一层的所有元素
for (int i = 0; i < str.length(); i++) {
char[] chars = str.toCharArray();
for (char c = 'a'; c <= 'z'; c++) {
chars[i] = c;
String word = new String(chars);
// Found the end word
if (word.equals(end)) return level + 1;
// Put it to the queue
if (dict.contains(word) && !visited.contains(word)) {
queue.add(word);
visited.add(word);
}
}
}
} else {
level++;
if (!queue.isEmpty()) {
queue.add(null);
}
}
}
return 0;
}