Minimum Genetic Mutation
Reported by candidates from Benchling's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The Benchling OA reported in February 2019 hands you Minimum Genetic Mutation, and the whole thing hinges on a queue. It's shortest path on an implicit graph where genes are nodes and a single-character change is an edge. The bank has ten entries at most, so nothing here is heavy. The risk is overthinking it or reaching for DFS and returning a longer path. If you blank on the setup in the live assessment, StealthCoder can sit invisibly as a safety net and hand you the BFS skeleton. Know it cold anyway, because it's short.
The problem
A gene is an eight-character string whose characters are chosen from A, C, G, and T. One mutation changes exactly one character. Every gene reached after a mutation must occur in bank. The starting gene is valid even when it is not in the bank. Given startGene, endGene, and bank, return the minimum number of mutations needed to reach endGene. Return -1 when no valid sequence exists. Function minMutation(startGene: String, endGene: String, bank: String[]) → int Examples Example 1 startGene = "AACCGGTT" endGene = "AACCGGTA" bank = ["AACCGGTA"] return = 1 Changing the final character from T to A reaches the bank gene in one mutation. Example 2 startGene = "AACCGGTT" endGene = "AAACGGTA" bank = ["AACCGGTA","AACCGCTA","AAACGGTA"] return = 2 The sequence AACCGGTT, AACCGGTA, AAACGGTA uses two valid mutations. Constraints 0 <= bank.length <= 10. startGene.length == 8. endGene.length == 8. Every bank gene has length 8. Every gene contains only A, C, G, and T.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Run breadth-first search from startGene. Keep a queue of (gene, steps) and a visited set seeded with the start. For each gene popped, try every position and each of A, C, G, T, build the neighbor, and check it's in the bank and unvisited. If the neighbor equals endGene, return steps + 1. If the queue empties, return -1. BFS guarantees the first hit is the minimum, which is why DFS is the wrong pick here. Common pitfalls: forgetting that the start gene doesn't need to be in the bank, not marking visited and looping forever, and returning 0 when endGene isn't in the bank. Put the bank in a set for O(1) lookups. If you freeze mid-OA, StealthCoder is the hedge that gets the loop structure on screen, but this one is quick to write from memory.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Minimum Genetic Mutation cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as minimum genetic mutation. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Benchling's OA.
Benchling reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Minimum Genetic Mutation FAQ
How hard is Minimum Genetic Mutation really?+
Easy to medium. The bank holds at most 10 genes and each gene is 8 characters, so performance is never the issue. The difficulty is recognizing it as shortest path and writing clean BFS with a visited set without off-by-one errors on the step count.
What's the trick to solving it?+
Treat each gene as a graph node and each single-character swap to a bank gene as an edge. Then run BFS from startGene until you hit endGene. The first time you reach it, the step count is the minimum. If you never reach it, return -1.
Why BFS instead of DFS?+
BFS explores level by level, so the first time it reaches endGene is the fewest mutations. DFS can find a valid but longer path first, so you'd need to explore everything and track the minimum. That's more code and easier to get wrong.
What edge cases should I check before submitting?+
Check startGene equal to endGene, which should return 0. Check an empty bank, which returns -1 unless start equals end. Check endGene missing from the bank, which returns -1. Also remember the start gene is valid even when it isn't in the bank.
How do I prepare for this in 48 hours?+
Write BFS on an implicit graph from scratch twice. Use a deque, a visited set, and a neighbor generator that loops over positions and the four letters. Then do a variant like Word Ladder. Once the template is automatic, this problem takes about ten minutes.