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

89 阅读4分钟

问题描述

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

思路解析

1.(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:

  • 增加一个碱基
  • 删除一个碱基
  • 替换一个碱基
  1. 创建一个 (len1 + 1) x (len2 + 1) 的二维数组 dp,其中 len1 和 len2 分别是 dna1 和 dna2 的长度。
  • dp[i][j] 表示将 dna1 的前 i 个字符转换成 dna2 的前 j 个字符所需的最少编辑步骤。
    • 如果 dna2 为空,那么将 dna1 转换成 dna2 需要删除 dna1 的所有字符,因此 dp[i][0] = i
    • 如果 dna1 为空,那么将 dna1 转换成 dna2 需要插入 dna2 的所有字符,因此 dp[0][j] = j
  1. 如果 dna1[i-1] == dna2[j-1],那么不需要进行任何编辑操作,dp[i][j] = dp[i-1][j-1]

  • 否则,我们需要考虑三种编辑操作:

    • 删除:删除 dna1 的第 i 个字符,dp[i][j] = dp[i-1][j] + 1
    • 插入:在 dna1 的第 i 个字符后插入 dna2 的第 j 个字符,dp[i][j] = dp[i][j-1] + 1
    • 替换:将 dna1 的第 i 个字符替换为 dna2 的第 j 个字符,dp[i][j] = dp[i-1][j-1] + 1
  • 取这三种操作的最小值作为 dp[i][j] 的值。

  1. dp[len1][len2] 即为将 dna1 转换成 dna2 所需的最少编辑步骤。

算法步骤

  1. 定义状态

    • 我们使用一个二维数组 dp,其中 dp[i][j] 表示将 dna1 的前 i 个字符转换为 dna2 的前 j 个字符所需的最少编辑次数。
  2. 初始化边界条件

    • 当 dna2 为空时,将 dna1 转换为空字符串需要删除 dna1 的所有字符,因此 dp[i][0] = i
    • 当 dna1 为空时,将空字符串转换为 dna2 需要插入 dna2 的所有字符,因此 dp[0][j] = j
  3. 状态转移方程

    • 如果 dna1[i-1] == dna2[j-1],则不需要进行任何编辑操作,dp[i][j] = dp[i-1][j-1]

    • 否则,我们需要考虑三种编辑操作:

      • 删除:删除 dna1 的第 i 个字符,dp[i][j] = dp[i-1][j] + 1
      • 插入:在 dna1 的第 i 个字符后插入 dna2 的第 j 个字符,dp[i][j] = dp[i][j-1] + 1
      • 替换:将 dna1 的第 i 个字符替换为 dna2 的第 j 个字符,dp[i][j] = dp[i-1][j-1] + 1
    • 最终,dp[i][j] 取上述三种操作中的最小值。

  4. 返回结果

    • 最终结果为 dp[len1][len2],即从 dna1 转换到 dna2 的最少编辑次数。

复杂度解析

通过使用两行数组来存储子问题的解,我们可以将空间复杂度从 `O(m * n)` 优化到 `O(n)`,同时保持时间复杂度为 `O(m * n)`。

code

`def solution(dna1, dna2): # 获取两个DNA序列的长度 len1, len2 = len(dna1), len(dna2)

# 创建一个二维数组来存储子问题的解
dp = [[0] * (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):
        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][j - 1] + 1,    # 插入
                           dp[i - 1][j - 1] + 1) # 替换

return dp[len1][len2]

if name == "main": # 测试用例 print(solution("AGCTTAGC", "AGCTAGCT") == 2) # True print(solution("AGCCGAGC", "GCTAGCT") == 4) # True `

AI刷题总结

  • 精准定位学习需求:AI刷题平台通过智能算法分析用户的学习数据,识别出用户的强项和弱项,从而推荐更有针对性的题目。这种个性化的题目推荐避免了用户在不熟悉的题目上浪费时间,而是将精力集中在最需要提升的领域,加速了学习进程。
  • 及时反馈:AI刷题平台能够在用户完成题目后立即给出答案解析,帮助用户快速了解自己的错误在哪里。这种即时反馈比等待老师批改或者自己慢慢核对答案要高效得多,有助于用户趁热打铁,加深对知识点的理解。