
一、题目描述

二、算法原理
思路: BFS算法 + 哈希表快速查找

我们可以发现这起始就是边权为 1 的最短路径问题:
我们要创建两个哈希表,一个用来存储以往入队列的字符串,防止我们枚举的合法的字符串再次入队列,另外一个存储基因库,用来快速查找我们枚举的字符串是否是合法的;
怎么把当前的字符串枚举出合法(即:属于基于库、不属于过往的入队列的字符串),使用两个for循环,每次固定一个字符,把 A'、'C'、'G' 和 'T' 枚举进去,此时就能实现枚举出来;
三、代码实现
cpp
class Solution {
string target;
int ret;
unordered_set<string> hash_b;//基因库
public:
int minMutation(string startGene, string endGene, vector<string>& bank) {
target = "ACGT";
for(auto& e : bank)//便于后续快速找到当前字符串是否在 bank 中
{
hash_b.insert(e);
}
queue<string> que;
ret = 0;
unordered_map<string,bool> hash_str;//防止以往的序列入 hash_str
hash_str[startGene] = true;
que.push(startGene);
while(que.size())
{
int flor = que.size();//剥离的次数
ret++;//剥离的层数
while(flor--)
{
string str = que.front();
que.pop();
if(Check(str,endGene,hash_str,que)) return ret;
}
}
return -1;
}
bool Check(string& str,string& end,unordered_map<string,bool>& hash_str,queue<string>& que)
{
for(int i = 0; i < str.size(); i++)
{
for(int j = 0; j < target.size(); j++)//枚举可能组合的序列
{
char ch = str[i];
str[i] = target[j];
if(hash_b.count(str) && !hash_str.count(str))
{
if(str == end) return true;
hash_str[str] = true;
que.push(str);
}
str[i] = ch;
}
}
return false;
}
};