伴学笔记之题解4 | 豆包MarsCode AI刷题

43 阅读3分钟

题目解析

81 古生物序列分析 本题要求计算两条 DNA 序列之间的最小变异次数,即编辑距离(Edit Distance)。这是经典的动态规划问题,涉及三种操作:

  1. 插入:在其中一条 DNA 序列中插入一个字符;
  2. 删除:从其中一条 DNA 序列中删除一个字符;
  3. 替换:将其中一条 DNA 序列的字符替换为另一个字符。

解题思路

动态规划建模

设 dp[i][j] 表示将 DNA1 的前 ii 个字符与 DNA2 的前 jj 个字符匹配所需的最小变异次数。

状态转移方程
  1. 如果当前字符相同(即 dna1[i1]=dna2[j1]\text{dna1}[i-1] = \text{dna2}[j-1]):

    dp[i][j]=dp[i1][j1]dp[i][j] = dp[i-1][j-1]

    • 不需要进行操作,直接继承子问题的结果。
  2. 如果当前字符不同(即 dna1[i1]dna2[j1]\text{dna1}[i-1] \neq \text{dna2}[j-1])

    dp[i][j]=min(dp[i1][j1]+1,dp[i1][j]+1,dp[i][j1]+1)dp[i][j] = \min(dp[i-1][j-1] + 1, dp[i-1][j] + 1, dp[i][j-1] + 1)

    • 替换操作:从 dp[i-1][j-1] 转移,加 1;
    • 删除操作:从 dp[i-1][j] 转移,加 1;
    • 插入操作:从 dp[i][j-1] 转移,加 1。
初始化
  • dp[i][0] = i:将 DNA1 的前 i 个字符变为空字符串需要 i 次删除操作;
  • dp[0][j] = j:将空字符串变为 DNA2 的前 j 个字符需要 j 次插入操作。
最终结果
  • dp[n][m]:即将 DNA1 的前 n 个字符与 DNA2 的前 m 个字符匹配的最小变异次数。

算法实现

Python 代码

def min_dna_mutations(dna1, dna2):
    n, m = len(dna1), len(dna2)
    
    # 初始化 DP 表
    dp = [[0] * (m + 1) for _ in range(n + 1)]
    
    # 初始化边界条件
    for i in range(n + 1):
        dp[i][0] = i
    for j in range(m + 1):
        dp[0][j] = j
    
    # 填充 DP 表
    for i in range(1, n + 1):
        for j in range(1, m + 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-1], dp[i-1][j], dp[i][j-1]) + 1
    
    # 返回最终结果
    return dp[n][m]

# 测试样例
print(min_dna_mutations("AGT", "AGCT"))          # 输出: 1
print(min_dna_mutations("AACCGGTT", "AACCTTGG")) # 输出: 4
print(min_dna_mutations("ACGT", "TGC"))          # 输出: 3
print(min_dna_mutations("A", "T"))               # 输出: 1
print(min_dna_mutations("GGGG", "TTTT"))         # 输出: 4

示例解析

示例 1

输入:dna1 = "AGT", dna2 = "AGCT"

两条 DNA 序列分别为:

  • AGT
  • AGCT

通过插入一个 "C" ,可以使两条序列相同。最小变异次数为 1。

示例 3

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

  1. 替换 "A" 为 "T";
  2. 删除 "C";
  3. 删除 "T"。

最小变异次数为 3。


复杂度分析

  1. 时间复杂度

    • 动态规划表需要填充O(n×m)O(n \times m),其中 n 和 m 分别为两条 DNA 序列的长度。
  2. 空间复杂度

    • 动态规划表占用 O(n×m)O(n \times m) 的空间。如果使用滚动数组优化,可以将空间复杂度降为 O(min(n,m))O(\min(n, m))

总结

本题通过动态规划解决,核心在于明确状态转移和初始化边界条件。通过构建编辑距离的动态规划表,可以高效计算两条 DNA 序列之间的最小变异次数,为实际生物学研究中分析 DNA 相似性提供了理论支持。动态规划的关键在于拆解问题,将整体问题划分为可管理的子问题,并通过状态转移方程递归地解决每个子问题,最终得到全局最优解。在本题中,编辑距离的计算直接反映了两条 DNA 序列在匹配过程中的变异次数,通过插入、删除或替换操作,逐步将一条序列转变为另一条序列。该方法不仅适用于 DNA 序列,还广泛应用于文本对比、拼写纠错、字符串匹配等领域,体现了动态规划方法的普适性和高效性。分析过程清晰且结果精准,为实际应用提供了可靠的算法支持。