LeeCode 433 最小基因变化

LeeCode 433 最小基因变化

题目描述:

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

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

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

另有一个基因库 bank 记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。

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

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

标签: 广度优先搜索,字符串比较

建立模型

本题的核心问题是寻找当前基因的所有可达基因序列(即一次基因变化得到的在基因库中的基因序列),然后依次迭代得到目标基因序列,并在迭代过程中记录变化次数。

编码实现

import queue

def minMutation(start: str, end: str, bank: List[str]) -> int:
    if not (end in bank) or (len(start) != len(end)):
        return -1
    if not (start in bank):
        bank.append(start)
    
    changes = 0
    q = queue.Queue()    # 使用队列存储可达基因序列和变化次数
    used = set()         # 集合保存到达过的基因序列,避免进入死循环
    q.put((start, changes))
    used.add(start)
    
    while not q.empty():
        cur = q.get()    # 弹出队首元组
        for i in range(len(bank)):
            if not (bank[i] in used) and compareTwoString(cur[0], bank[i]):
                if bank[i] == end:
                    return cur[1] + 1
                q.put((bank[i], cur[1] + 1))
                used.append(bank[i])
    return -1

def compareTwoString(str1: str, str2: str) -> bool:
    """
    判断两个基因序列是否能通过一次基因变化得到
    """
    if len(str1) != len(str2):
        return False
    count = 0
    for i in range(len(str1)):
        count += 1 if str1[i] != str2[i] else 0
    return count == 1
posted @ 2022-05-07 22:36  ylyzty  阅读(26)  评论(0编辑  收藏  举报