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