Welcome to Subscribe On Youtube
433. Minimum Genetic Mutation
Description
A gene string can be represented by an 8-character long string, with choices from 'A'
, 'C'
, 'G'
, and 'T'
.
Suppose we need to investigate a mutation from a gene string startGene
to a gene string endGene
where one mutation is defined as one single character changed in the gene string.
- For example,
"AACCGGTT" --> "AACCGGTA"
is one mutation.
There is also a gene bank bank
that records all the valid gene mutations. A gene must be in bank
to make it a valid gene string.
Given the two gene strings startGene
and endGene
and the gene bank bank
, return the minimum number of mutations needed to mutate from startGene
to endGene
. If there is no such a mutation, return -1
.
Note that the starting point is assumed to be valid, so it might not be included in the bank.
Example 1:
Input: startGene = "AACCGGTT", endGene = "AACCGGTA", bank = ["AACCGGTA"] Output: 1
Example 2:
Input: startGene = "AACCGGTT", endGene = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"] Output: 2
Constraints:
0 <= bank.length <= 10
startGene.length == endGene.length == bank[i].length == 8
startGene
,endGene
, andbank[i]
consist of only the characters['A', 'C', 'G', 'T']
.
Solutions
BFS or DFS.
-
class Solution { public int minMutation(String start, String end, String[] bank) { Set<String> s = new HashSet<>(); for (String b : bank) { s.add(b); } Map<Character, String> mp = new HashMap<>(4); mp.put('A', "TCG"); mp.put('T', "ACG"); mp.put('C', "ATG"); mp.put('G', "ATC"); Deque<Pair<String, Integer>> q = new LinkedList<>(); q.offer(new Pair<>(start, 0)); while (!q.isEmpty()) { Pair<String, Integer> p = q.poll(); String t = p.getKey(); int step = p.getValue(); if (end.equals(t)) { return step; } for (int i = 0; i < t.length(); ++i) { for (char c : mp.get(t.charAt(i)).toCharArray()) { String next = t.substring(0, i) + c + t.substring(i + 1); if (s.contains(next)) { q.offer(new Pair<>(next, step + 1)); s.remove(next); } } } } return -1; } }
-
class Solution { public: int minMutation(string start, string end, vector<string>& bank) { unordered_set<string> s; for (auto& b : bank) s.insert(b); unordered_map<char, string> mp; mp['A'] = "TCG"; mp['T'] = "ACG"; mp['C'] = "ATG"; mp['G'] = "ATC"; queue<pair<string, int>> q; q.push({start, 0}); while (!q.empty()) { auto p = q.front(); q.pop(); string t = p.first; int step = p.second; if (t == end) return step; for (int i = 0; i < t.size(); ++i) { for (char c : mp[t[i]]) { string next = t.substr(0, i) + c + t.substr(i + 1, t.size() - i - 1); if (s.count(next)) { q.push({next, step + 1}); s.erase(next); } } } } return -1; } };
-
class Solution: def minMutation(self, start: str, end: str, bank: List[str]) -> int: s = set(bank) q = deque([(start, 0)]) mp = {'A': 'TCG', 'T': 'ACG', 'C': 'ATG', 'G': 'ATC'} while q: t, step = q.popleft() if t == end: return step for i, v in enumerate(t): for j in mp[v]: next = t[:i] + j + t[i + 1 :] if next in s: q.append((next, step + 1)) s.remove(next) return -1
-
func minMutation(start string, end string, bank []string) int { s := make(map[string]bool) for _, b := range bank { s[b] = true } mp := make(map[byte]string) mp['A'] = "TCG" mp['T'] = "ACG" mp['C'] = "ATG" mp['G'] = "ATC" type pair struct { first string second int } q := []pair{ {start, 0} } for len(q) > 0 { p := q[0] q = q[1:] t, step := p.first, p.second if t == end { return step } for i := 0; i < len(t); i++ { for _, c := range mp[t[i]] { next := t[:i] + string(c) + t[i+1:] if s[next] { q = append(q, pair{next, step + 1}) s[next] = false } } } } return -1 }
-
function minMutation(start: string, end: string, bank: string[]): number { const queue = [start]; let res = 0; while (queue.length !== 0) { const n = queue.length; for (let i = 0; i < n; i++) { const s1 = queue.shift(); if (s1 === end) { return res; } for (let j = bank.length - 1; j >= 0; j--) { const s2 = bank[j]; let count = 0; for (let k = 0; k < 8; k++) { if (s1[k] !== s2[k]) { count++; } } if (count <= 1) { queue.push(...bank.splice(j, 1)); } } } res++; } return -1; }
-
use std::collections::VecDeque; impl Solution { pub fn min_mutation(start: String, end: String, mut bank: Vec<String>) -> i32 { let mut queue = vec![start].into_iter().collect::<VecDeque<String>>(); let mut res = 0; while !queue.is_empty() { let n = queue.len(); for _ in 0..n { let s1 = queue.pop_front().unwrap(); if s1 == end { return res; } for i in (0..bank.len()).rev() { let s1 = s1.as_bytes(); let s2 = bank[i].as_bytes(); let mut count = 0; for j in 0..8 { if s1[j] != s2[j] { count += 1; } } if count <= 1 { queue.push_back(bank.remove(i)); } } } res += 1; } -1 } }