
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)252Please respect copyright.PENANALayhjTSDsP
// better than use DFS as it just need to find out the shortest path.
class Solution {252Please respect copyright.PENANAdk54Xt1X0e
public int minMutation(String start, String end, String[] bank) {252Please respect copyright.PENANAMOPwi6P5wv
// 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.252Please respect copyright.PENANA50l8l0iTgu
Queue<String> queue = new LinkedList<>();252Please respect copyright.PENANAV0YCxeiNGj
Set<String> seen = new HashSet<>();252Please respect copyright.PENANAUX95u8UycD
queue.add(start);252Please respect copyright.PENANA9I8FLAZKgt
seen.add(start);252Please respect copyright.PENANA1skWSRlBvI
252Please respect copyright.PENANAohVDk1M2fn
int steps = 0;252Please respect copyright.PENANApiOBGniE38
252Please respect copyright.PENANAmC2Y1Gyxzd
while (!queue.isEmpty()) {252Please respect copyright.PENANAejg2HjsB0U
int nodesInQueue = queue.size();252Please respect copyright.PENANAjp89eDQZKK
for (int j = 0; j < nodesInQueue; j++) {252Please respect copyright.PENANAqRFy6NVCd3
String node = queue.remove();252Please respect copyright.PENANANrUUIL1Ebb
// 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)) {252Please respect copyright.PENANAVCQEpU3z0Z
return steps;252Please respect copyright.PENANACfZijXkAf3
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {252Please respect copyright.PENANAs9f2Brksuk
for (int i = 0; i < node.length(); i++) {252Please respect copyright.PENANAlX99sAR3zs
String neighbor = node.substring(0, i) + c + node.substring(i + 1);252Please respect copyright.PENANA9M2N55bSsQ
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {252Please respect copyright.PENANAPOh1YsEpqp
queue.add(neighbor);252Please respect copyright.PENANAJOdbF3Z9sQ
seen.add(neighbor);252Please respect copyright.PENANAvrjPzCbppj
}252Please respect copyright.PENANAC8q5Sd2Ehy
}252Please respect copyright.PENANAC4zZV9MqRV
}252Please respect copyright.PENANAS3WghmiTUU
}252Please respect copyright.PENANAL1qAdqPoYu
252Please respect copyright.PENANApmE74qzM44
steps++;252Please respect copyright.PENANAjcRUyCRJGt
}252Please respect copyright.PENANAgUyzvwojZz
// If we finish the BFS and did not find end, return -1.252Please respect copyright.PENANAJ32lxsgtEU
return -1;252Please respect copyright.PENANA4fmOCJUWQg
}252Please respect copyright.PENANAo07HEOa17y
}