Leetcode 433. Minimum Genetic Mutation
LeetCode Problem 433: Minimum Genetic Mutation
A gene string can be represented by an 8-character long string, with characters from the set {'A', 'C', 'G', 'T'}
.
Given a gene start
string, a gene end
string, and a list of bank
strings (all of which represent valid genetic sequences), return the minimum number of mutations needed to transform the start
gene to the end
gene using the following rules:
bank
.If it is not possible to mutate the start
gene to the end
gene, return -1
.
start
or end
is not in the bank
?
start
does not need to be in the bank, but end
must be in the bank
for a valid transformation to exist.bank
contains distinct strings.bank
guaranteed to be 8 characters long and composed of {A, C, G, T}
?
This problem can be formulated as an unweighted graph traversal problem where each gene string is a node and an edge exists between two nodes if they differ by exactly one character (i.e., one mutation).
start
gene string.end
gene string.end
is reached during BFS, return the number of steps taken.end
is not in the bank
, immediately return -1
.n
is the number of strings in the bank.#include <iostream>
#include <vector>
#include <unordered_set>
#include <queue>
#include <string>
using namespace std;
// Function to check if two strings differ by exactly one character
bool oneMutationApart(const string &s1, const string &s2) {
int diffCount = 0;
for (int i = 0; i < s1.size(); ++i) {
if (s1[i] != s2[i]) {
++diffCount;
if (diffCount > 1) return false;
}
}
return diffCount == 1;
}
int minMutation(string start, string end, vector<string>& bank) {
unordered_set<string> bankSet(bank.begin(), bank.end());
if (!bankSet.count(end)) return -1;
queue<pair<string, int>> bfsQueue;
bfsQueue.push({start, 0});
unordered_set<string> visited;
visited.insert(start);
vector<char> genes = {'A', 'C', 'G', 'T'};
while (!bfsQueue.empty()) {
auto [current, steps] = bfsQueue.front();
bfsQueue.pop();
if (current == end) {
return steps;
}
for (int i = 0; i < current.size(); ++i) {
char originalChar = current[i];
for (char gene : genes) {
if (gene == originalChar) continue;
current[i] = gene;
if (bankSet.count(current) && !visited.count(current)) {
bfsQueue.push({current, steps + 1});
visited.insert(current);
}
}
current[i] = originalChar; // revert back for the next iteration
}
}
return -1;
}
int main() {
string start = "AACCGGTT";
string end = "AACCGGTA";
vector<string> bank = {"AACCGGTA"};
cout << "Minimum mutations: " << minMutation(start, end, bank) << endl;
return 0;
}
bank
to an unordered_set for O(1) look-up times.end
string is reached, return the number of mutations; otherwise, when the traversal is complete and end
is not reached, return -1.Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?