
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)259Please respect copyright.PENANAxPWuixiwb5
// better than use DFS as it just need to find out the shortest path.
class Solution {259Please respect copyright.PENANAh9E5YhohDB
public int minMutation(String start, String end, String[] bank) {259Please respect copyright.PENANAMglYz0bnV2
// 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.259Please respect copyright.PENANAETneVReiGe
Queue<String> queue = new LinkedList<>();259Please respect copyright.PENANAKGLL6WaQOI
Set<String> seen = new HashSet<>();259Please respect copyright.PENANASoWLEWFBup
queue.add(start);259Please respect copyright.PENANAp8fOoFNmIJ
seen.add(start);259Please respect copyright.PENANAZNNxroT3On
259Please respect copyright.PENANAaYkK3F08Cf
int steps = 0;259Please respect copyright.PENANAHlYgGD2SIL
259Please respect copyright.PENANAsWnscpYNtc
while (!queue.isEmpty()) {259Please respect copyright.PENANA7DZ2zEDbn3
int nodesInQueue = queue.size();259Please respect copyright.PENANA9eoW3r11o0
for (int j = 0; j < nodesInQueue; j++) {259Please respect copyright.PENANAapF4t14Vjf
String node = queue.remove();259Please respect copyright.PENANAnaBZiChbAX
// 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)) {259Please respect copyright.PENANAKLWe57HvEW
return steps;259Please respect copyright.PENANAsVa5XH9J68
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {259Please respect copyright.PENANAaeGsqhFx7P
for (int i = 0; i < node.length(); i++) {259Please respect copyright.PENANAAdNKA50iUx
String neighbor = node.substring(0, i) + c + node.substring(i + 1);259Please respect copyright.PENANA9mh9JBnUHA
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {259Please respect copyright.PENANAZOKtWBgfos
queue.add(neighbor);259Please respect copyright.PENANALNqaxjcixR
seen.add(neighbor);259Please respect copyright.PENANAijWFiFBlav
}259Please respect copyright.PENANAm7UjjGryOS
}259Please respect copyright.PENANAMUaVxjmb13
}259Please respect copyright.PENANAoEtFgN1IbR
}259Please respect copyright.PENANA4pAiGJhYrA
259Please respect copyright.PENANAhSfdizXEPx
steps++;259Please respect copyright.PENANATe4ewQGoXi
}259Please respect copyright.PENANA2C2vioIh9F
// If we finish the BFS and did not find end, return -1.259Please respect copyright.PENANAamvXCNUei7
return -1;259Please respect copyright.PENANAESjPUcr1uq
}259Please respect copyright.PENANAQNAFpaqfZE
}