当前位置: 面试刷题>> 最小基因变化(经典算法150题)


### 题目描述 **最小基因变化** 给定一个基因字符串 `startGene` 表示起始基因,一个字符串数组 `targetGenes` 表示目标基因集合,以及一个字符串 `bank` 表示基因库(即所有可能的基因变异字符串)。基因字符串仅由 `'A'`, `'C'`, `'G'`, `'T'` 这四个字符组成。 基因可以通过一次变异从一个基因变为另一个基因,变异指的是将一个字符替换为基因库中的任意一个字符。请找出从起始基因 `startGene` 到目标基因集合 `targetGenes` 中的某个基因所需的最少变异次数。如果没有可能到达目标基因集合,则返回 `-1`。 **示例 1**: ``` 输入: startGene = "AACCGGTT", targetGenes = ["AACCGGTA"], bank = ["AACCGGTA"] 输出: 1 解释: 起始基因可以通过一次变异得到目标基因 "AACCGGTA"。 ``` **示例 2**: ``` 输入: startGene = "AACCGGTT", targetGenes = ["AAACGGTA","AACCGCTA","AAACGGTA"], bank = ["AACCGGTA","AACCGCTA","AAACGGTA"] 输出: 2 解释: 可以通过两次变异从起始基因得到第一个或第三个目标基因。 ``` **示例 3**: ``` 输入: startGene = "AAAA", targetGenes = ["AAAA"], bank = ["AAAA"] 输出: 0 解释: 起始基因和目标基因相同,无需变异。 ``` ### 解题思路 这是一个图搜索问题,可以使用广度优先搜索(BFS)算法来解决。我们可以将基因视为图中的节点,如果两个基因只相差一个字符,则它们之间存在一条边。起始基因是起点,目标基因集合中的基因是终点。 1. **初始化**:创建一个队列用于BFS,将起始基因和变异次数0一起入队。同时,使用一个集合来记录已经访问过的基因,避免重复访问。 2. **BFS遍历**:在遍历过程中,对于队列中的每个基因,尝试将其每个字符替换为基因库中的其他字符,生成所有可能的变异基因。如果某个变异基因存在于目标基因集合中,则返回当前的变异次数。如果变异基因尚未被访问过,则将其加入队列和已访问集合中,并继续搜索。 3. **结束条件**:如果队列为空时仍未找到目标基因,则返回-1。 ### PHP 示例代码 ```php function minMutation($startGene, $targetGenes, $bank) { $visited = array_flip($bank); // 使用数组翻转作为集合,快速查找 $queue = new SplQueue(); $queue->enqueue([$startGene, 0]); // [基因, 变异次数] while (!$queue->isEmpty()) { [$gene, $steps] = $queue->dequeue(); if (in_array($gene, $targetGenes)) { return $steps; } for ($i = 0; $i < strlen($gene); $i++) { $originalChar = $gene[$i]; for ($j = 0; $j < strlen('ACGT'); $j++) { $newChar = 'ACGT'[$j]; if ($newChar != $originalChar) { $newGene = substr_replace($gene, $newChar, $i, 1); if (isset($visited[$newGene])) { unset($visited[$newGene]); // 标记为已访问 $queue->enqueue([$newGene, $steps + 1]); } } } } } return -1; } ``` 注意:由于PHP标准库中没有直接的队列实现,这里使用了`SplQueue`。另外,`$visited`数组通过`array_flip`初始化为基因库的反向索引,以快速检查一个基因是否已访问过。 ### Python 和 JavaScript 示例代码 由于篇幅限制,这里不再重复展示完整的Python和JavaScript代码,但它们的实现思路与PHP类似,只是语法和库的使用有所不同。Python可以使用`collections.deque`作为队列,JavaScript可以使用数组模拟队列操作。同时,它们也都会使用集合(Python的`set`,JavaScript的`Set`)来记录已访问的基因。
推荐面试题