
Q: 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 start to a gene string end 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 start and end and the gene bank bank, return the minimum number of mutations needed to mutate from start to end. 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.
A: BFS (Breadth-First Search)268Please respect copyright.PENANAhxPMoYeaQY
// better than use DFS as it just need to find out the shortest path.
class Solution {268Please respect copyright.PENANAxwpjB2UpUJ
public int minMutation(String start, String end, String[] bank) {268Please respect copyright.PENANAV69gFWJJ8D
// Initialize a queue queue and a set seen. The queue will be used for BFS and the set will be used to prevent visiting a node more than once. Initially, the queue and set should hold start.268Please respect copyright.PENANAnTmUVmYFau
Queue<String> queue = new LinkedList<>();268Please respect copyright.PENANAfn3tBW66da
Set<String> seen = new HashSet<>();268Please respect copyright.PENANA4U4NlBtUCS
queue.add(start);268Please respect copyright.PENANALDBQ2EJwaT
seen.add(start);268Please respect copyright.PENANATmVpMBv47c
268Please respect copyright.PENANAcyi0Yc7Z2m
int steps = 0;268Please respect copyright.PENANAhTkwtHeBaw
268Please respect copyright.PENANA18SQn7UjTU
while (!queue.isEmpty()) {268Please respect copyright.PENANAEQ5REKjclM
int nodesInQueue = queue.size();268Please respect copyright.PENANAV0tj4IMvvH
for (int j = 0; j < nodesInQueue; j++) {268Please respect copyright.PENANA6fEDbXLTy6
String node = queue.remove();268Please respect copyright.PENANAoQfToDNzhC
// Perform a BFS. At each node, if node == end, return the number of steps so far. Otherwise, iterate over all the neighbors. For each neighbor, if neighbor is not in seen and neighbor is in bank, add it to queue and seen.
if (node.equals(end)) {268Please respect copyright.PENANAviRdGCGBa5
return steps;268Please respect copyright.PENANAI9ztNhHoji
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {268Please respect copyright.PENANAWoc693HlTa
for (int i = 0; i < node.length(); i++) {268Please respect copyright.PENANAzKnicvgJZj
String neighbor = node.substring(0, i) + c + node.substring(i + 1);268Please respect copyright.PENANAZ6mgrRfQQo
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {268Please respect copyright.PENANATIkk8Cp8sb
queue.add(neighbor);268Please respect copyright.PENANAYJEbP4HD1R
seen.add(neighbor);268Please respect copyright.PENANAYHOl19LBMk
}268Please respect copyright.PENANAnPYmDhUuQA
}268Please respect copyright.PENANAOQopagVbJe
}268Please respect copyright.PENANA3oDSYKb0mA
}268Please respect copyright.PENANAR3UO0UBvB2
268Please respect copyright.PENANAvyjL6QBmv9
steps++;268Please respect copyright.PENANAVowaTMlks3
}268Please respect copyright.PENANAkeMZTL9eez
// If we finish the BFS and did not find end, return -1.268Please respect copyright.PENANAEVH80qJ9MQ
return -1;268Please respect copyright.PENANAgO7ba2EMzp
}268Please respect copyright.PENANALpPuNAc9Ac
}