
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)235Please respect copyright.PENANAvpTumNtJKQ
// better than use DFS as it just need to find out the shortest path.
class Solution {235Please respect copyright.PENANAlCL6ZuZIeX
public int minMutation(String start, String end, String[] bank) {235Please respect copyright.PENANA8Gf55CbvPJ
// 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.235Please respect copyright.PENANAFqU1JESg32
Queue<String> queue = new LinkedList<>();235Please respect copyright.PENANAtVRrU36pmL
Set<String> seen = new HashSet<>();235Please respect copyright.PENANABZqpM6Ds2p
queue.add(start);235Please respect copyright.PENANArwfEMh8BsZ
seen.add(start);235Please respect copyright.PENANAkeDBcGKHVc
235Please respect copyright.PENANApXU2AZsvkI
int steps = 0;235Please respect copyright.PENANAEOjBZtiRxt
235Please respect copyright.PENANAlo04RLOYA3
while (!queue.isEmpty()) {235Please respect copyright.PENANAm5oFSRi7KN
int nodesInQueue = queue.size();235Please respect copyright.PENANARO5FPkH3wm
for (int j = 0; j < nodesInQueue; j++) {235Please respect copyright.PENANAzBSVe17mm7
String node = queue.remove();235Please respect copyright.PENANAWyOWHugODH
// 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)) {235Please respect copyright.PENANAJ3Rjo3NASB
return steps;235Please respect copyright.PENANA43Iyeu88Hv
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {235Please respect copyright.PENANAuSKuYWzHlB
for (int i = 0; i < node.length(); i++) {235Please respect copyright.PENANAYJvKvcPIxE
String neighbor = node.substring(0, i) + c + node.substring(i + 1);235Please respect copyright.PENANAEo5NU7yK0u
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {235Please respect copyright.PENANAr82ujyXEyB
queue.add(neighbor);235Please respect copyright.PENANAaqcFwH9ODf
seen.add(neighbor);235Please respect copyright.PENANAXaDqSms6MS
}235Please respect copyright.PENANAV2IuoSoPBc
}235Please respect copyright.PENANA3q8O4bGRWg
}235Please respect copyright.PENANApWgAhkA9Q4
}235Please respect copyright.PENANAj2qbnGid1M
235Please respect copyright.PENANAEKlABObP7d
steps++;235Please respect copyright.PENANA52krOz8o4k
}235Please respect copyright.PENANAwTawSAXo3O
// If we finish the BFS and did not find end, return -1.235Please respect copyright.PENANAqRYEK7pq0K
return -1;235Please respect copyright.PENANA2RA0y1ybjo
}235Please respect copyright.PENANAGM8D7BFsM7
}