题目链接:https://leetcode.com/problems/minimum-genetic-mutation/#/description
A gene string can be represented by an 8-character long string, with choices from "A"
, "C"
, "G"
, "T"
.
Suppose we need to investigate about a mutation (mutation from "start" to "end"), where ONE mutation is defined as ONE single character changed in the gene string.
For example, "AACCGGTT"
-> "AACCGGTA"
is 1 mutation.
Also, there is a given gene "bank", which records all the valid gene mutations. A gene must be in the bank to make it a valid gene string.
Now, given 3 things - start, end, bank, your task is to determine what is the minimum number of mutations needed to mutate from "start" to "end". If there is no such a mutation, return -1.
Note:
- Starting point is assumed to be valid, so it might not be included in the bank.
- If multiple mutations are needed, all mutations during in the sequence must be valid.
- You may assume start and end string is not the same.
Example 1:
start: "AACCGGTT"
end: "AACCGGTA"
bank: ["AACCGGTA"]
return: 1
Example 2:
start: "AACCGGTT"
end: "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]
return: 2
Example 3:
start: "AAAAACCC"
end: "AACCCCCC"
bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]
return: 3
class Solution {
public:
int minMutation(string start, string end, vector<string>& bank) {
queue<string> toVisit;
unordered_set<string> dict(bank.begin(),bank.end());
int dist=0;
if(start==end)
return dist;
if(!dict.count(end))
return -1;
toVisit.push(start);
dist=1;
while(!toVisit.empty())
{
int n=toVisit.size();
for(int k=0;k<n;k++)
{
string top=toVisit.front();
toVisit.pop();
dict.erase(top);
for(int i=0;i<top.size();i++)
{
string tmp=top;
for(auto c:"ACGT")
{
tmp[i]=c;
if(tmp==end)
return dist;
if(dict.count(tmp))
{
toVisit.push(tmp);
dict.erase(tmp);
}
}
}
}
dist++;
}
return -1;
}
};
class Solution {
public:
int minMutation(string start, string end, vector<string>& bank) {
queue<string> toVisit;
unordered_set<string> dict(bank.begin(), bank.end());
int dist = 0;
if(!dict.count(end)) return -1;
toVisit.push(start);
dict.insert(start); dict.insert(end);
while(!toVisit.empty())
{
int n = toVisit.size();
for(int i=0; i<n; i++)
{
string str = toVisit.front();
toVisit.pop();
if(str==end) return dist;
addWord(str, dict, toVisit);
}
dist++;
}
return -1;
}
void addWord(string word, unordered_set<string>& dict, queue<string>& toVisit) {
dict.erase(word);
for(int i=0; i<word.size(); i++)
{
char tmp = word[i];
for(char c:string("ACGT"))
{
word[i] = c;
if(dict.count(word))
{
toVisit.push(word);
dict.erase(word);
}
}
word[i] = tmp;
}
}
};