给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列比如:
1.每次只能改变一个字母。
2.变换过程中的中间单词必须在字典中出现。
您在真实的面试中是否遇到过这个题?
Yes
样例
给出数据如下:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
一个最短的变换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的长度 5
注意
•如果没有转换序列则返回0。
•所有单词具有相同的长度。
•所有单词都只包含小写字母。
标签 Expand
相关题目 Expand
解题思路:
1.宽度优先搜索,BFS。超时。
public class Solution {
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return an integer
*/
public int ladderLength(String start, String end, Set<String> dict) {
// write your code here
if (start.length() != end.length())
return 0;
Set<String> visited = new HashSet<>();
visited.add(start);
Queue<String> curQueue = new LinkedList<>();
curQueue.add(start);
int res = 0;
while (curQueue != null&&curQueue.size()>0) {
res++;
Queue<String> nextQueue = new LinkedList<>();
while(curQueue!=null&&curQueue.size()>0){
String curstr = curQueue.poll();
visited.add(curstr);
for(String dictstr:dict){
if(!visited.contains(dict)&&diffOneword(dictstr, curstr)){
if(diffOneword(end, curstr)){
return res+1;
}
nextQueue.add(dictstr);
}
}
}
curQueue = nextQueue;
}
return 0;
}
public boolean diffOneword(String source, String s) {
if (source.length() != s.length())
return false;
int count = 0;
for (int i = 0; i < source.length(); i++) {
if (source.charAt(i) != s.charAt(i)) {
count++;
}
}
if (1 == count) {
return true;
} else {
return false;
}
}
}
优化算法:在进行选择下一层节点时候,可以将该字符串的没一个字符修改为a-z,这样每次选择时候,时间复杂度是O(26*O(curstr.length)),没有优化时候是O(O(dict.length)*O(curstr.length))
public class Solution {
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return an integer
*/
public int ladderLength(String start, String end, Set<String> dict) {
// write your code here
if (start == null || end == null || start.equals(end)
|| start.length() != end.length()){
return 0;
}
Queue<String> queue=new LinkedList<String>();
HashMap<String,Integer> dist=new HashMap<String,Integer>();
queue.add(start);
dist.put(start, 1);
while(!queue.isEmpty()){
String head=queue.poll();
int headDist=dist.get(head);
//从每一个位置开始替换成a~z
for(int i=0;i<head.length();i++){
for(char j='a';j<'z';j++){
if(head.charAt(i)==j) continue;
StringBuilder sb=new StringBuilder(head);
sb.setCharAt(i, j);
if(sb.toString().equals(end)) return headDist+1;
if(dict.contains(sb.toString())&&!dist.containsKey(sb.toString())){
queue.add(sb.toString());
dist.put(sb.toString(), headDist+1);
}
}
}
}
return 0;
}
}