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)145Please respect copyright.PENANAYar5CzI5ro
// better than use DFS as it just need to find out the shortest path.
class Solution {145Please respect copyright.PENANAS0nXtqhNY0
public int minMutation(String start, String end, String[] bank) {145Please respect copyright.PENANAp9sBo4rQk6
// 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.145Please respect copyright.PENANA65OeBr8udi
Queue<String> queue = new LinkedList<>();145Please respect copyright.PENANAAEXWGdZ45G
Set<String> seen = new HashSet<>();145Please respect copyright.PENANA685Kd2KtNz
queue.add(start);145Please respect copyright.PENANAS91kEW43N6
seen.add(start);145Please respect copyright.PENANAwB7eqYUCtl
145Please respect copyright.PENANArgo4t4yd9S
int steps = 0;145Please respect copyright.PENANAslm0SmIk1F
145Please respect copyright.PENANAcFo4D7wFQ5
while (!queue.isEmpty()) {145Please respect copyright.PENANAeA8uDJIZOV
int nodesInQueue = queue.size();145Please respect copyright.PENANAz3psuB5Jgq
for (int j = 0; j < nodesInQueue; j++) {145Please respect copyright.PENANAn6Lh2wP1fK
String node = queue.remove();145Please respect copyright.PENANAglMEUk9RIS
// 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)) {145Please respect copyright.PENANA5QU9hwrYrC
return steps;145Please respect copyright.PENANACOJlNnMyeX
}
for (char c: new char[] {'A', 'C', 'G', 'T'}) {145Please respect copyright.PENANAhhVn0xri2O
for (int i = 0; i < node.length(); i++) {145Please respect copyright.PENANAlschSOUC9G
String neighbor = node.substring(0, i) + c + node.substring(i + 1);145Please respect copyright.PENANA72GiqFBCuk
if (!seen.contains(neighbor) && Arrays.asList(bank).contains(neighbor)) {145Please respect copyright.PENANAsxvtSxEtXj
queue.add(neighbor);145Please respect copyright.PENANA8RBgWMJWJR
seen.add(neighbor);145Please respect copyright.PENANAlKg4JXl9th
}145Please respect copyright.PENANAyu0uJP4h7S
}145Please respect copyright.PENANANQRmFm6w7h
}145Please respect copyright.PENANAvGoXcEthmp
}145Please respect copyright.PENANAEfmzzmmmdQ
145Please respect copyright.PENANAoPbyTTBTCn
steps++;145Please respect copyright.PENANA2TzVrP2Pie
}145Please respect copyright.PENANAYs0MaxMB2e
// If we finish the BFS and did not find end, return -1.145Please respect copyright.PENANAQIf00rNMS9
return -1;145Please respect copyright.PENANAriQGXIPBAL
}145Please respect copyright.PENANANaBua3OZ10
}