题目地址:
https://leetcode.com/problems/minimum-genetic-mutation/
给定两段基因序列
s
s
s和
e
e
e,再给定一个字符串数组
A
A
A,从
s
s
s开始,每次允许将某个字母变为'A', 'C', 'G', 'T'
其中一个,并且要求变化完成之后的字符串在
A
A
A里,问至少要多少步可以变为
e
e
e。
可以用双向BFS。代码如下:
class Solution {
public:
int minMutation(string start, string end, vector<string>& bank) {
string gs = "ACGT";
unordered_set<string> st(bank.begin(), bank.end());
if (!st.count(end)) return -1;
if (start == end) return 0;
queue<string> bq, eq;
unordered_set<string> bvis, evis;
bq.push(start);
eq.push(end);
bvis.insert(start);
evis.insert(end);
int res = 0;
while (bq.size() && eq.size()) {
res++;
if (bq.size() <= eq.size()) {
if (one_step(bq, bvis, evis, st, gs)) return res;
} else {
if (one_step(eq, evis, bvis, st, gs)) return res;
}
}
return -1;
}
bool one_step(queue<string>& bq, unordered_set<string>& bvis,
unordered_set<string>& evis, unordered_set<string>& st,
string& gs) {
for (int i = bq.size(); i; i--) {
auto s = bq.front();
bq.pop();
for (int j = 0; j < s.size(); j++) {
char old = s[j];
for (char g : gs) {
if (old == g) continue;
s[j] = g;
if (st.count(s) && !bvis.count(s)) {
if (evis.count(s)) return true;
bvis.insert(s);
bq.push(s);
}
}
s[j] = old;
}
}
return false;
}
};
时间复杂度 O ( l s 2 l A ) O(l_s^2l_A) O(ls2lA),空间 O ( l s l A ) O(l_sl_A) O(lslA)。