给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列
比如:
- 每次只能改变一个字母。
- 变换过程中的中间单词必须在字典中出现。
您在真实的面试中是否遇到过这个题?
样例
给出数据如下:
start ="hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
一个最短的变换序列是"hit" ->"hot"-> "dot" -> "dog" ->"cog",
返回它的长度 5
说明:在网上找到最多的就是这个方法,应该也是最好的方法了吧。求最短路径的BFS广度遍历算法。
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if(start.size() != end.size())
return 0;
if(start.empty() || end.empty()||dict.empty())
return 0;
queue<string> path;//广度遍历都需要借助队列,存放着当前出队节点的所有子节点。
path.push(start); //第一个单词入队--开始节点
map<string,int> count;//存放从开始节点到该节点的距离
count[start]=1; //开始节点存放着1
dict.erase(start); //避免走回头路 所以需要保证dict中无重复节点
while(dict.size()>0 && !path.empty()){
string curword = path.front(); //头结点出队!
path.pop();
int n=count[curword];
for(int i = 0; i < curword.size(); i++){ //嵌套的两个for循环作用是搜索出队节点的子节点
string tmp = curword; //这里子节点的定义是指与该节点(该字符串)仅有一个字符不同的
for(char j='a'; j<='z'; j++){ //的节点(该字符串)
if(tmp[i]==j)
continue;
else
tmp[i]=j; //把curword的第i-1个字符改变成另一个字符(从‘a’到‘z’逐个试探)
if(dict.find(tmp) != dict.end()){//如果改变后的字符串tmp在dict里面,说明curword和tmp相连
path.push(tmp); //入队
count[tmp]=n+1; //计入距离
dict.erase(tmp); //用完了就可以删除了 因为BFS每个节点只经过一次
}
if(tmp==end)
return count[tmp]; //tmp正好等end的话直接返回,因为BFS是层次遍历,越到后面层次会越深
} //所以前面到达的必然是最小值!
}
}
return 0;
}
};