
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.PENANAqa8WPQTooT
// better than use DFS as it just need to find out the shortest path.
class Solution {275Please respect copyright.PENANANcaGjoILiM
public int minMutation(String start, String end, String[] bank) {275Please respect copyright.PENANAXQSulOoLgu
// 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.PENANAFoiK61h7gX
Queue<String> queue = new LinkedList<>();275Please respect copyright.PENANAGeIWTJ3OQp
Set<String> seen = new HashSet<>();275Please respect copyright.PENANAozBG1v0dP9
queue.add(start);275Please respect copyright.PENANAwxL8LmLGAg
seen.add(start);275Please respect copyright.PENANAS7DbgPR8aF
275Please respect copyright.PENANAMt71Ina4PZ
int steps = 0;275Please respect copyright.PENANA59vYM0qVu9
275Please respect copyright.PENANAwfGaG6AIpv
while (!queue.isEmpty()) {275Please respect copyright.PENANAzZz5lpmqJI
int nodesInQueue = queue.size();275Please respect copyright.PENANA6qQpSenYrr
for (int j = 0; j < nodesInQueue; j++) {275Please respect copyright.PENANAOIT1AdeITO
String node = queue.remove();275Please respect copyright.PENANAXB1kwyjW3d
// 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.PENANAddjzXux6DH
return steps;275Please respect copyright.PENANABgan2nq47U
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {275Please respect copyright.PENANAbEgtfPrhTA
for (int i = 0; i < node.length(); i++) {275Please respect copyright.PENANAYiYv95RBVn
String neighbor = node.substring(0, i) + c + node.substring(i + 1);275Please respect copyright.PENANAut3PmiPv0I
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {275Please respect copyright.PENANAEIiP1I3JIc
queue.add(neighbor);275Please respect copyright.PENANArUd4dvUShm
seen.add(neighbor);275Please respect copyright.PENANAhQPJb3qfeC
}275Please respect copyright.PENANA0GpgBZya2z
}275Please respect copyright.PENANAh9qWT5GeLF
}275Please respect copyright.PENANA5aSXVeWcoJ
}275Please respect copyright.PENANAlbhmSV1FUT
275Please respect copyright.PENANAa571fF7GCE
steps++;275Please respect copyright.PENANANhLBEWsSPA
}275Please respect copyright.PENANAjefiwHNd1S
// If we finish the BFS and did not find end, return -1.275Please respect copyright.PENANAWMVYjsUhv8
return -1;275Please respect copyright.PENANA9DfmHWmYx6
}275Please respect copyright.PENANA3RRLDOCI1S
}