Advertisement

Minimum Genetic Mutation - LeetCode 433 Solution

Minimum Genetic Mutation - Complete Solution Guide

Minimum Genetic Mutation is LeetCode problem 433, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

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 startGene to a gene string endGene 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

Detailed Explanation

The problem asks us to find the minimum number of single-character mutations required to transform a starting gene string (`startGene`) into a target gene string (`endGene`). The mutations must be valid, meaning each intermediate gene string must exist in a given gene bank (`bank`). A gene string consists of 8 characters, each being one of 'A', 'C', 'G', or 'T'. The starting gene is considered valid, even if it is not in the bank. If a path to the end gene doesn't exist using valid mutations, return -1.

Solution Approach

The solution uses Breadth-First Search (BFS) to explore possible mutations. The `startGene` is the starting node. In each step, we generate all possible one-character mutations of the current gene. If a mutated gene is present in the `bank` and hasn't been visited, we add it to the queue for further exploration and mark it as visited. The BFS continues until we reach the `endGene` or the queue is empty (meaning no path exists).

Step-by-Step Algorithm

  1. Step 1: Check if `startGene` is the same as `endGene`. If so, return 0 (no mutations needed).
  2. Step 2: Convert the `bank` list to a set (`bank_set`) for faster lookups.
  3. Step 3: Check if `endGene` is present in the `bank_set`. If not, return -1 because the target is unreachable.
  4. Step 4: Initialize a queue with `startGene` and a mutation count of 0. Also, initialize a `visited` set to keep track of visited genes.
  5. Step 5: While the queue is not empty, dequeue a gene and its mutation count.
  6. Step 6: If the dequeued gene is the `endGene`, return the mutation count.
  7. Step 7: For each character in the current gene (8 characters):
  8. Step 8: Iterate through all possible characters ('A', 'C', 'G', 'T').
  9. Step 9: If the current character is the same as the original character at that position, skip it.
  10. Step 10: Create a new gene string by replacing the character at the current position with the new character.
  11. Step 11: Check if the new gene is in `bank_set` and not in `visited`. If both are true:
  12. Step 12: Add the new gene to `visited`. Enqueue the new gene and increment the mutation count.
  13. Step 13: If the queue becomes empty without finding the `endGene`, return -1 (no path exists).

Key Insights

  • Insight 1: Breadth-First Search (BFS) is ideal for finding the shortest path in an unweighted graph. We can represent each gene as a node, and mutations between genes as edges.
  • Insight 2: The gene bank acts as a constraint; we can only explore nodes (genes) that are present in the bank.
  • Insight 3: To prevent infinite loops, we need to keep track of visited genes. A hash set is perfect for efficient lookup.

Complexity Analysis

Time Complexity: O(B*L)

Space Complexity: O(B)

Topics

This problem involves: Hash Table, String, Breadth-First Search.

Companies

Asked at: X.