这道算法题,输入是两个word(string类型),begin和end.和一个string的集合wordDict(set),里面有不同的word(string),输出要求为一个从begin变换为end且每次只允许变动一个字母的最短变换长度。所有的word都有相同的长度,都是小写字母,且每次只允许变换一个字母。
这道题,因为输入中有集合,考虑用BFS(广度优先搜索)的方法。
广度优先搜索的原理就不赘述了,具体谈谈实现方法。采用两个无序集合head,tail,两个指向无序集合的指针phead,ptail.
初始将phead指向head集合,将ptail指向tail集合。变换长度dist为2,因为一步转换的长度就是2.
构造一个辅助集合temp,对于phead指向集合中的所有元素,遍历一遍,找出wordDict中所有可以一步变换的元素,加入temp,并从WordDict中删去。
将phead指向temp,如果head或tail变空,结束循环,返回dist,否则,将phead指向长度较短的一个集合,进行上一行的运算。(为了减少运算)
代码如下:
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
unordered_set<string> head, tail, *phead, *ptail;
head.insert(beginWord);
tail.insert(endWord);
int dist = 2;
while (!head.empty() && !tail.empty()) {
if (head.size() <= tail.size()) {
phead = &head;
ptail = &tail;
}
else {
phead = &tail;
ptail = &head;
}
unordered_set<string> temp;
for (auto itr = phead -> begin(); itr != phead -> end(); itr++) {
string word = *itr;
wordDict.erase(word);
for (int p = 0; p < (int)word.length(); p++) {
char letter = word[p];
for (int k = 0; k < 26; k++) {
word[p] = 'a' + k;
if (ptail -> find(word) != ptail -> end())
return dist;
if (wordDict.find(word) != wordDict.end()) {
temp.insert(word);
wordDict.erase(word);
}
}
word[p] = letter;
}
}
dist++;
swap(*phead, temp);
}
return 0;
}
};