
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)275Please respect copyright.PENANA36iHBXwcnE
// better than use DFS as it just need to find out the shortest path.
class Solution {275Please respect copyright.PENANAACSqdwRbOv
public int minMutation(String start, String end, String[] bank) {275Please respect copyright.PENANAvmqz8HXsZq
// 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.275Please respect copyright.PENANA6nwhU6Et1p
Queue<String> queue = new LinkedList<>();275Please respect copyright.PENANAa1dxueKpzP
Set<String> seen = new HashSet<>();275Please respect copyright.PENANAvLtpQo8rO0
queue.add(start);275Please respect copyright.PENANArjvOXzEA3Y
seen.add(start);275Please respect copyright.PENANAhmlD2Dm4zx
275Please respect copyright.PENANAX8K4Nes58h
int steps = 0;275Please respect copyright.PENANAci3QhsNxxK
275Please respect copyright.PENANAkp5B3B5Zf3
while (!queue.isEmpty()) {275Please respect copyright.PENANATAwZ4JyZlb
int nodesInQueue = queue.size();275Please respect copyright.PENANAU2BhPU7nwf
for (int j = 0; j < nodesInQueue; j++) {275Please respect copyright.PENANApJJSgCmR4a
String node = queue.remove();275Please respect copyright.PENANAt2hoDSmVei
// 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)) {275Please respect copyright.PENANADAuVRMfCea
return steps;275Please respect copyright.PENANAR8AsWWK9Bt
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {275Please respect copyright.PENANAP8jDmXIoFB
for (int i = 0; i < node.length(); i++) {275Please respect copyright.PENANAA23CuYxJJD
String neighbor = node.substring(0, i) + c + node.substring(i + 1);275Please respect copyright.PENANAddVQZYtISd
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {275Please respect copyright.PENANAmIwjpv48yb
queue.add(neighbor);275Please respect copyright.PENANA0WVznXtdLw
seen.add(neighbor);275Please respect copyright.PENANAKCjdGUGM6M
}275Please respect copyright.PENANAIm0zgPvI9N
}275Please respect copyright.PENANAd6EQ0rzrQL
}275Please respect copyright.PENANA1GDMOCZsaE
}275Please respect copyright.PENANAEHshawsfft
275Please respect copyright.PENANANK5aV7dt4M
steps++;275Please respect copyright.PENANArXkQyVdr8N
}275Please respect copyright.PENANAPKRnVkAU8R
// If we finish the BFS and did not find end, return -1.275Please respect copyright.PENANAAZTDofDaIq
return -1;275Please respect copyright.PENANA7z9SHP4YWn
}275Please respect copyright.PENANA7DDABmbXUH
}