青训营X豆包MarsCode 解题:DNA序列编辑距离 | 豆包MarsCode AI刷题

69 阅读2分钟

1.题目描述

问题描述

小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。

示例1

输入:dna1 = "AACCGGTT",dna2 = "AACCTTGG" 输出:4

示例2

输入:dna1 = "ACGT",dna2 = "TGC" 输出:3

难度等级

简单

题目链接

[](DNA序列编辑距离 - MarsCode)

2.解题思路

创立一个二维数组,进行加减操作,从上一步最小的基础上再加一步,一直迭代到最后一个碱基,取最小值即为答案。 dp=[[0]*(len2+1) for _ in range(len1+1)]创建一个dp数组,大小为(len1+1)*(len2+1), 初始化 dp 数组的第一行和第一列

for i in range(len1+1):
    dp[i][0]=i
for j in range(len2+1):
    dp[0][j]=j

再进行迭代,要注意下面要用到i-1和j-1,所以从迭代时要1开始。然后分两种情况,即碱基一致时,不进行操作;碱基不一致时,选择插入(dp[i][j-1])、删除(dp[i-1][j])或替换(dp[i-1][j-1])操作的最小值加1

 for i in range(1,len1+1):
    for j in range(1,len2+1):
        if dna1[i-1]==dna2[j-1]:
            dp[i][j]=dp[i-1][j-1]
        else:
            dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1

最后返回从dna1到dna2的最小编辑距离即dp[len1][len2]

3.代码实现

def solution(dna1, dna2):
    # Please write your code here
    len1=len(dna1)
    len2=len(dna2)
    dp=[[0]*(len2+1) for _ in range(len1+1)]#创建一个dp数组并初始化,大小为(len1+1)*(len2+1)
    for i in range(len1+1)://只进行删除操作
        dp[i][0]=i
    for j in range(len2+1)://只进行插入操作
        dp[0][j]=j
    for i in range(1,len1+1)://注意下面要用到i-1和j-1,所以从1开始。
        for j in range(1,len2+1):
            if dna1[i-1]==dna2[j-1]://碱基一致时,不进行操作
                dp[i][j]=dp[i-1][j-1]
            else://否则,我们选择插入(dp[i][j-1])、删除(dp[i-1][j])或替换(dp[i-1][j-1])操作的最小值加1
                dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
    return dp[len1][len2]//返回从dna1到dna2的最小编辑距离


if __name__ == "__main__":
    #  You can add more test cases here
    print(solution("AGCTTAGC", "AGCTAGCT") == 2 )
    print(solution("AGCCGAGC", "GCTAGCT") == 4)

4.总结

以上是我对这道题的解法,主要运用dp动态规划,有更好的方法希望可以指教,谢谢你观看到这里,祝大家刷题顺利。