433. Minimum Genetic Mutation
start: "AACCGGTT"
end: "AACCGGTA"
bank: ["AACCGGTA"]
return: 1start: "AACCGGTT"
end: "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]
return: 2Last updated
start: "AACCGGTT"
end: "AACCGGTA"
bank: ["AACCGGTA"]
return: 1start: "AACCGGTT"
end: "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]
return: 2Last updated
start: "AAAAACCC"
end: "AACCCCCC"
bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]
return: 3// Single-End BFS
int minMutation(string start, string end, vector<string>& bank) { // time: O(n * str_len); space: O(n * str_len)
unordered_set<string> genes(bank.begin(), bank.end());
queue<string> q({start});
string choices = "ACGT";
int res = 0;
while (!q.empty()) {
for (int k = q.size() - 1; k >= 0; --k) {
string gene = q.front(); q.pop();
if (gene == end) return res;
for (int i = 0; i < gene.length(); ++i) {
string newGene = gene;
for (const char& ch : choices) {
newGene[i] = ch;
if (genes.count(newGene) && newGene != gene) {
q.push(newGene);
genes.erase(newGene); // avoid visit it twice
}
}
}
}
++res;
}
return -1;
}// Double-End BFS
int minMutation(string start, string end, vector<string>& bank) { // time: O(n * str_len); space: O(n * str_len)
unordered_set<string> genes(bank.begin(), bank.end());
if (!genes.count(end)) return -1;
unordered_set<string> q1({start}), q2({end});
string choices = "ACGT";
int res = 0;
while (!q1.empty() && !q2.empty()) {
if (q1.size() > q2.size()) swap(q1, q2);
unordered_set<string> tmp;
for (const string& gene : q1) {
for (int i = 0; i < 8; ++i) {
string newGene = gene;
for (const char& ch : choices) {
newGene[i] = ch;
if (q2.count(newGene)) return res + 1;
if (!genes.count(newGene)) continue;
genes.erase(newGene); // avoid visiting it twice
tmp.insert(newGene);
}
}
}
++res;
swap(q1, tmp);
}
return -1;
}