目录

0433:最小基因变化(★)

力扣第 433 题

题目

基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 'A''C''G''T' 之一。

假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。

  • 例如,"AACCGGTT" --> "AACCGGTA" 就是一次基因变化。

另有一个基因库 bank 记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。(变化后的基因必须位于基因库 bank 中)

给你两个基因序列 startend ,以及一个基因库 bank ,请你找出并返回能够使 start 变化为 end 所需的最少变化次数。如果无法完成此基因变化,返回 -1

注意:起始基因序列 start 默认是有效的,但是它并不一定会出现在基因库中。

示例 1:

输入:start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
输出:1

示例 2:

输入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
输出:2

示例 3:

输入:start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"]
输出:3

提示:

  • start.length == 8
  • end.length == 8
  • 0 <= bank.length <= 10
  • bank[i].length == 8
  • startendbank[i] 仅由字符 ['A', 'C', 'G', 'T'] 组成

分析

  • 典型的 bfs,数据量较大时,可以类似 0127
    • 将单词的某一位改为 ‘.’ 作为单词的 key
    • 每个单词按所有的 key 存在哈希表中
    • 搜索时,取所有 key 对应的列表即可

解答

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution:
    def minMutation(self, startGene: str, endGene: str, bank: List[str]) -> int:
        d = defaultdict(list)
        for w in bank:
            for i in range(len(w)):
                d[w[:i]+'*'+w[i+1:]].append(w)
        Q,vis = deque([(startGene,0)]), {startGene}
        while Q:
            u,w = Q.popleft()
            if u==endGene:
                return w
            for i in range(len(u)):
                for v in d[u[:i]+'*'+u[i+1:]]:
                    if v not in vis:
                        Q.append((v,w+1))
                        vis.add(v)
        return -1

33 ms