Leetcode 433. 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
Thinking:
We can think this problem is a tree. That each level we will change a character in start
, which has 3 conditions each time. Then we do the BFS and if we find the end
, return the level.
Code:
public class Solution {
public int minMutation(String start, String end, String[] bank) {
if(start.length() != 8 || end.length() != 8 || bank == null || bank.length == 0) return -1;
HashSet<String> bankSet = new HashSet<>();
for(String str : bank){
bankSet.add(str);
}
if(! bankSet.contains(end)) return -1;
Queue<String> Q = new LinkedList<>();
char[] gene = {'A','C','G','T'};
int count = 1;
int level = 0;
Q.offer(start);
while(!Q.isEmpty()){
while(count > 0){
String current = Q.poll();
if(current.equals(end)){
return level;
}
char[] currentArray = current.toCharArray();
for(int i =0; i < currentArray.length; i++){
char origin = currentArray[i];
for(char chr : gene){
if(chr == currentArray[i]){
continue;
}
currentArray[i] = chr;
String next = new String(currentArray);
if(bankSet.contains(next)){
bankSet.remove(next);
Q.offer(next);
}
}
currentArray[i] = origin;
}
count--;
}
count = Q.size();
level++;
}
return -1;
}
}
Conclusion:
We need to use some idea of the backtracking that we need to let the currentArray[i]
become the origin
at the end of each loop.