Word Ladder
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
.
由于本题递推关系是1个字母变化。那么能够建立起1对多的联系。又是找最短距离,那么采用图的广度优先遍历BFS是合适的。
解题的过程中有如下几个问题需要解决:
1、虽然是图模型是BFS,但是没有必要建立一个图的存储结构。即时找到下一层节点就行了。
2、由于最终返回的是最短距离,所以广度优先遍历如何获取“解所在第几层”需要设计(可以用隔板来分层,可以另外用一个队列同步来存层数信息)。
3、如何获取下一个“单词”(即下一层节点)?如果用“当前”去字典中逐个比较判断是否只有一个letter差异,显然当dict大的时间慢。可以将当前单词,每个字母从a~z,进行足够变化,去dict(哈希存储)中查找,可能更有效。
以下博文分析的较为透彻:
http://blog.csdn.net/yutianzuijin/article/details/12887747
http://blog.csdn.net/lydyangliu/article/details/25574067
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if(start==end) return 1;
queue<string> Q;
queue<int> depth; //用来计算深度
Q.push(start);
depth.push(1);
while(!Q.empty()){
string cur=Q.front();
Q.pop();
int dep=depth.front();
depth.pop();
for(int i=0;i<cur.size();i++){ //从每一个位置开始替换成a~z
for(int j=0;j<26;j++){
if(cur[i]!='a'+j){
string target(cur);
target[i]='a'+j;
if(target==end) return dep+1;
if(findItem(target,dict)){
Q.push(target);
depth.push(dep+1);
}
}
}
}
}
return 0;
}
private:
bool findItem(string target,unordered_set<string> &dict){
unordered_set<string>::iterator iter;
iter=dict.find(target);
if(iter!=dict.end()){
dict.erase(iter);
return true;
}
else
return false;
}
};