想着倒是简单,建个邻接矩阵或者邻接链表(不过应该很很占空间吧),因为每次变化对应的单词到单词的距离都是1,所以是抽象出来是一个无权重的无向图,然后就应该是求个最短路径了。unorderred_set是C++11标准里的,按照说明是用Hash进行元素查找,所以每次find都是常数时间(具体参见cplusplus.com)。不过还是先从网上瞄了一个用的广度优先搜索的代码,自己按照这个思路写了一下:
class Solution{
public:
int ladderLength(string start, string end, unordered_set
&dict) {
int dst = 2;
string SEP = "|";
queue
memo;
memo.push(start);
memo.push(SEP);
while (!memo.empty()) {
string cur = memo.front();
memo.pop();
if (cur == SEP) {
if (memo.empty()) {
break;
} else {
++dst;
memo.push(SEP);
continue;
}
}
for (size_t i = 0; i < cur.length(); i++) { // traverse all the possible one distance words
char tmp = cur[i]; // save the character in position i
for (char ch='a'; ch <= 'z'; ch++) { // traverse all the possible one distance words by changing cur[i]
if (ch == tmp) continue; // skip original word
cur[i] = ch; // replace character in position i
if (cur == end) { // find it!
return dst;
}
unordered_set
::iterator iter = dict.find(cur);
if (iter != dict.end()) { // if word with one distance from the current exists in the dict
memo.push(cur);
dict.erase(iter);
}
}
cur[i] = tmp; // restore
}
}
return 0;
}
};
csdn的编辑器真tmd烂总是多出些莫名其妙的html标签来,怎么把这些<string/>去掉啊。
关于广度优先搜索的实现,自己在队列里加了个特殊字符作为分割符,来标记深度的递增过程,这个是自己的土办法。参考的那份代码使用两个队列一个专门用来push,一个专门用来pop,然后在深度递增的过程中不断转换两者的角色,还是很巧妙啊!