
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)161Please respect copyright.PENANAIguZcCG5T0
// better than use DFS as it just need to find out the shortest path.
class Solution {161Please respect copyright.PENANAqLdkS5fXRb
public int minMutation(String start, String end, String[] bank) {161Please respect copyright.PENANAKi8r4QatAj
// 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.161Please respect copyright.PENANAqFUIK3jKdq
Queue<String> queue = new LinkedList<>();161Please respect copyright.PENANAdz4W04mC3Q
Set<String> seen = new HashSet<>();161Please respect copyright.PENANAFGCGGMLDBe
queue.add(start);161Please respect copyright.PENANAgkuvJgyYHY
seen.add(start);161Please respect copyright.PENANA7ZTblV6b77
161Please respect copyright.PENANAawqfnzM70p
int steps = 0;161Please respect copyright.PENANAg8ShcVsYKE
161Please respect copyright.PENANAHATdB86qI8
while (!queue.isEmpty()) {161Please respect copyright.PENANAk9Ylfb3qNA
int nodesInQueue = queue.size();161Please respect copyright.PENANAurlAlg8rZs
for (int j = 0; j < nodesInQueue; j++) {161Please respect copyright.PENANAqbId6PUzI0
String node = queue.remove();161Please respect copyright.PENANA4sO8Vui7eb
// 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)) {161Please respect copyright.PENANAW4FZ19yvqR
return steps;161Please respect copyright.PENANAa9lmSgqCYx
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {161Please respect copyright.PENANAd9C4bavniS
for (int i = 0; i < node.length(); i++) {161Please respect copyright.PENANAyRQ2FyTlDn
String neighbor = node.substring(0, i) + c + node.substring(i + 1);161Please respect copyright.PENANA3xrEnxggn8
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {161Please respect copyright.PENANAguwlRt1mty
queue.add(neighbor);161Please respect copyright.PENANAruVibkDGLs
seen.add(neighbor);161Please respect copyright.PENANASMi9MDuVPU
}161Please respect copyright.PENANAmgZYnj22EP
}161Please respect copyright.PENANAuK7dmVnueb
}161Please respect copyright.PENANA9nfLyo0lOG
}161Please respect copyright.PENANAqB6coOnQfF
161Please respect copyright.PENANA0q1YzTxtjY
steps++;161Please respect copyright.PENANACijpHK5NnG
}161Please respect copyright.PENANALV114pC3xo
// If we finish the BFS and did not find end, return -1.161Please respect copyright.PENANAnbTlqtkMuH
return -1;161Please respect copyright.PENANAIBVL7BowBp
}161Please respect copyright.PENANAaflCruX9iN
}