Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
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; } };