
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)187Please respect copyright.PENANA3PmEVbGDvG
// better than use DFS as it just need to find out the shortest path.
class Solution {187Please respect copyright.PENANAPxKKNjYRy7
public int minMutation(String start, String end, String[] bank) {187Please respect copyright.PENANALPjFibZbas
// 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.187Please respect copyright.PENANAR5bfYrQBeL
Queue<String> queue = new LinkedList<>();187Please respect copyright.PENANADWcFKyYp28
Set<String> seen = new HashSet<>();187Please respect copyright.PENANAuOwtBtp2x8
queue.add(start);187Please respect copyright.PENANA1OuSkDBjed
seen.add(start);187Please respect copyright.PENANAtxki0X4orj
187Please respect copyright.PENANA1D9Iwi6E3X
int steps = 0;187Please respect copyright.PENANATNdbvW7lyj
187Please respect copyright.PENANA0621xkVHpQ
while (!queue.isEmpty()) {187Please respect copyright.PENANA9lMMMOFlJ7
int nodesInQueue = queue.size();187Please respect copyright.PENANAESioUmAPVK
for (int j = 0; j < nodesInQueue; j++) {187Please respect copyright.PENANA3xFJSfxsxL
String node = queue.remove();187Please respect copyright.PENANA7h5LS3BODv
// 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)) {187Please respect copyright.PENANAvJ7zLNvJ11
return steps;187Please respect copyright.PENANA4fa4fgOIQN
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {187Please respect copyright.PENANAVHojz3bMXs
for (int i = 0; i < node.length(); i++) {187Please respect copyright.PENANA9kEq1JiVqx
String neighbor = node.substring(0, i) + c + node.substring(i + 1);187Please respect copyright.PENANAy7GFwi1Ock
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {187Please respect copyright.PENANA3w5W3UE2ux
queue.add(neighbor);187Please respect copyright.PENANAUBA9w5M954
seen.add(neighbor);187Please respect copyright.PENANAtshTKdk4N2
}187Please respect copyright.PENANAe54Jc4anlc
}187Please respect copyright.PENANAliytUMRypq
}187Please respect copyright.PENANAoH2JO3OoZB
}187Please respect copyright.PENANAqzFVTiBZd9
187Please respect copyright.PENANAOBWjA3G86k
steps++;187Please respect copyright.PENANAokRwcd8IPP
}187Please respect copyright.PENANAQRs1MBhXik
// If we finish the BFS and did not find end, return -1.187Please respect copyright.PENANAjAoxE37qAP
return -1;187Please respect copyright.PENANAOgF2teaClN
}187Please respect copyright.PENANATlU6nHHzs6
}