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)124Please respect copyright.PENANA3gaLW0c1u7
// better than use DFS as it just need to find out the shortest path.
class Solution {124Please respect copyright.PENANAVn8YZab9A6
public int minMutation(String start, String end, String[] bank) {124Please respect copyright.PENANARmcK2df4Cj
// 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.124Please respect copyright.PENANARoHoElz6CB
Queue<String> queue = new LinkedList<>();124Please respect copyright.PENANASdEhcRxEtI
Set<String> seen = new HashSet<>();124Please respect copyright.PENANAkmZvtZTgi4
queue.add(start);124Please respect copyright.PENANAMH75nto1hw
seen.add(start);124Please respect copyright.PENANAURmc6pODar
124Please respect copyright.PENANArfUY0zkqcU
int steps = 0;124Please respect copyright.PENANAiZvsrDpxtF
124Please respect copyright.PENANAEGn97vRQJy
while (!queue.isEmpty()) {124Please respect copyright.PENANAK3kQaMhQ4m
int nodesInQueue = queue.size();124Please respect copyright.PENANAZVnxfNjQT6
for (int j = 0; j < nodesInQueue; j++) {124Please respect copyright.PENANADIva9nzDv9
String node = queue.remove();124Please respect copyright.PENANA8PztaIoQBo
// 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)) {124Please respect copyright.PENANAU5HXdXI55z
return steps;124Please respect copyright.PENANAcWFEJ53L3M
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {124Please respect copyright.PENANADJ4YMPTUs5
for (int i = 0; i < node.length(); i++) {124Please respect copyright.PENANA65noKPxuUC
String neighbor = node.substring(0, i) + c + node.substring(i + 1);124Please respect copyright.PENANAy6aObbZbPS
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {124Please respect copyright.PENANAbozfa01pYx
queue.add(neighbor);124Please respect copyright.PENANAX1S990pSC3
seen.add(neighbor);124Please respect copyright.PENANAiPAjiaODbb
}124Please respect copyright.PENANAPA5GEUtrXC
}124Please respect copyright.PENANA26cwtaQOV3
}124Please respect copyright.PENANAzmlNRX7wHg
}124Please respect copyright.PENANALaau16x8l0
124Please respect copyright.PENANACO8PMtV3p3
steps++;124Please respect copyright.PENANAJwgyiw41fL
}124Please respect copyright.PENANAAJvpPiNmoe
// If we finish the BFS and did not find end, return -1.124Please respect copyright.PENANA6gVKRy143U
return -1;124Please respect copyright.PENANA0O54ddtipH
}124Please respect copyright.PENANAe7LLF5pTXJ
}