DNA序列编辑距离 | 豆包MarsCode AI刷题

128 阅读4分钟

标题:DNA序列编辑距离 | 豆包MarsCode AI刷题

题目解析

思路

给定两个DNA序列 dna1dna2,需要计算将 dna1 编辑成 dna2 所需的最少操作次数。操作包括插入、删除或替换一个碱基。

我们可以使用动态规划来解决这个问题。设 dp[i][j] 表示 dna1[:i] 变成 dna2[:j] 的最小操作次数。状态转移方程如下:

  • 如果 dna1[i-1] == dna2[j-1],则 dp[i][j] = dp[i-1][j-1]
  • 否则,dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

其中,dp[i-1][j] 表示删除 dna1 中的一个字符,dp[i][j-1] 表示在 dna1 中插入一个字符,dp[i-1][j-1] 表示替换 dna1 中的一个字符。

图解

假设 dna1 = "AGT"dna2 = "AGCT",我们可以构建一个二维DP表:

AGCT
Ø0123
A0012
G1001
T2110

最终答案是 dp[len(dna1)][len(dna2)]

代码详解

def solution(dna1, dna2):
    len1 = len(dna1)
    len2 = len(dna2)
    
    # 创建一个二维数组存储中间结果
    dp = [[0 for _ in range(len2 + 1)] for _ in range(len1 + 1)]
    
    # 初始化边界值
    for i in range(len1 + 1):
        dp[i][0] = i
    for j in range(len2 + 1):
        dp[0][j] = j
    
    # 动态规划填充dp表格
    for i in range(1, len1 + 1):
        for j in range(1, len2 + 1):
            cost = 0 if dna1[i - 1] == dna2[j - 1] else 1
            dp[i][j] = min(dp[i - 1][j] + 1,     # 删除
                           dp[i][j - 1] + 1,     # 插入
                           dp[i - 1][j - 1] + cost)  # 替换
    
    return dp[len1][len2]

# 测试用例
print(solution("AGT", "AGCT"))  # 输出:1
print(solution("AACCGTT", "AACCCTGG"))  # 输出:4
print(solution("ACGT", "TGC"))  # 输出:3
print(solution("A", "T"))  # 输出:1
print(solution("AGCCGAGC", "GCTAGCT"))  # 输出:2
print(solution("AGCCGAGC", "GCTAGCT"))  # 输出:2
print(solution("AGT", "AGCT"))  # 输出:1
print(solution("AACCGTT", "AACCCTGG"))  # 输出:4
print(solution("ACGT", "TGC"))  # 输出:3
print(solution("A", "T"))  # 输出:1
print(solution("GGGG", "TTTT"))  # 输出:4

知识总结

  1. 动态规划:适用于求解具有最优子结构性质的问题,通过自底向上或自顶向下方式避免重复计算。动态规划的关键在于识别出问题的最优子结构,并且能够将大问题分解成更小的子问题来解决。在这个问题中,我们将整个DNA序列的编辑距离问题分解成了一个个子序列的编辑距离问题,从而降低了问题的复杂度。
  2. 编辑距离:衡量两个字符串之间差异的一种度量标准,常用于文本处理和生物信息学领域。编辑距离不仅可以用来比较两个字符串之间的相似程度,还可以应用于拼写检查、基因测序等领域。在这个问题中,我们通过计算两个DNA序列之间的编辑距离,来判断这两个序列的相似程度以及需要多少次操作才能使一个序列变成另一个序列。

学习计划

  1. 定期刷题:每周安排固定时间刷题,逐步提高难度。可以通过豆包MarsCode AI刷题平台,根据自己的水平和需求,选择适合自己的题目进行练习。同时,也可以尝试不同类型的题目,拓宽自己的知识面。
  2. 复盘总结:每做完一定数量的题目后,总结常见问题类型及解法。可以将自己的解题过程记录下来,以便日后查阅和复习。同时,也可以和其他人分享自己的经验和教训,共同进步。
  3. 实战演练:参加在线编程比赛,提升实际应用能力。通过参加各种编程比赛,可以在紧张刺激的比赛中检验自己的实力,同时也能够在比赛中结交志同道合的朋友,相互学习,共同成长。

工具运用

  1. 豆包MarsCode AI刷题:利用AI推荐系统,针对薄弱环节进行专项练习。豆包MarsCode AI刷题平台可以根据用户的历史答题情况,智能推荐适合用户的题目,帮助用户有针对性地进行练习,提高学习效率。
  2. 社区互动:参与技术论坛讨论,交流解题思路和经验。可以通过加入各种技术论坛和社区,与其他开发者交流解题思路和经验,扩大自己的视野,提高自己的技术水平。

通过上述方法,可以有效提升编程能力和解决问题的速度。