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
.
如果找不到这样的序列,则返回0;
思路:1. 利用BFS的思想,在dict中,寻找与hit相差一个字符的单词,并依次放到一个队列中,并将该单词作为key值,value为hit与该单词的距离,即1,放入map中;
2. 取出队列中的第一个单词,重复第一步要做的内容,只不过value的值为第一步加1;
3 . 重复上诉两步,知道队列为空为止(注意需将end加入到dict中);
在dict中寻找与hit相差一个字符的单词时,有一个技巧:直接的想法肯定会将hit与dict中每一个单词都进行比较,判断是否与hit只相差1个字符,这种判别方法适合单词数量少的dict,当单词很多时,并不适合,时间复杂度比较高;
因此利用的方法是改变hit中的每一个字符,分别从a到z(这里还没有考虑大小写问题,一直当作小写),判断修改后的单词是否在dict中,如在,则将它加入到队列中,这样时间复杂度为hit.length()×26;
下面是源代码
public int ladderLength(String start, String end, HashSet<String> dict) {
Queue<String> queue = new LinkedList<String>();// Queue is a interface
Map<String, Integer> map = new HashMap<String, Integer>();
queue.add(start);
map.put(start, 1);
dict.add(end);
while (!queue.isEmpty()) {
String temp = queue.poll();
// System.out.println(temp);
for (int i = 0; i < temp.length(); i++) {
for(char j = 'a' ; j<='z';j++){
StringBuilder strbud = new StringBuilder(temp);
strbud.setCharAt(i, j);
if(strbud.toString().equals(temp))continue;
if(dict.contains(strbud.toString())&&!map.containsKey(strbud.toString())){
queue.add(strbud.toString());
map.put(strbud.toString(),map.get(temp)+1);
}
}
}
}
if(map.containsKey(end)){
return map.get(end);
}
return 0;
}