【青训营笔记3】AI刷题笔记(DP1-DNA序列编辑距离)

82 阅读3分钟

使用AI编程刷经典DP题【DNA序列编辑距离】的笔记。

1. 问题描述

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

对于两个DNA序列 dna1dna2,求出最少的编辑步骤数,使得 dna1 能够转化为 dna2

2. 测试样例

样例1:

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

样例2:

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

样例3:

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

样例4:

输入:dna1 = "A", dna2 = "T"
输出:1

样例5:

输入:dna1 = "GGGG", dna2 = "TTTT"
输出:4

3. 解题思路

本问题是典型的 编辑距离问题,即通过最少的操作将一个字符串转换为另一个字符串。常见的动态规划算法可以用于求解。

  • 动态规划思路:设 dp[i][j] 为将 dna1 的前 i 个字符转换为 dna2 的前 j 个字符的最少操作数。
  • 状态转移:我们有三种操作:
    1. 删除操作:从 dna1 中删除一个字符,即 dp[i-1][j] + 1
    2. 插入操作:将 dna2[j-1] 插入到 dna1 中,即 dp[i][j-1] + 1
    3. 替换操作:如果 dna1[i-1] 不等于 dna2[j-1],进行替换操作,即 dp[i-1][j-1] + 1

通过上述转移方程,我们可以递推出整个 dp 数组,最终得到 dp[n][m],即将 dna1 完全转换为 dna2 所需要的最小操作数。

4. 代码实现

from functools import cache

def solution(dna1, dna2):
    n, m = len(dna1), len(dna2)
    
    # 使用缓存来优化递归
    @cache
    def dfs(i: int, j: int) -> int:
        if i < 0:
            return j + 1
        if j < 0:
            return i + 1
        # 如果字符相等,直接跳到下一个字符
        if dna1[i] == dna2[j]:
            return dfs(i - 1, j - 1)
        # 否则,进行替换、插入或删除操作
        return 1 + min(dfs(i - 1, j), dfs(i, j - 1), dfs(i - 1, j - 1))
    
    # 计算最少编辑步骤
    return dfs(n - 1, m - 1)

if __name__ == "__main__":
    print(solution("AGCTTAGC", "AGCTAGCT") == 2)
    print(solution("AGCCGAGC", "GCTAGCT") == 4)

5. AI练中学评价

  • 测试Prompt

需要一点思路提示。

  • 部分结果

解题思路

好的,让我们来分析一下这个问题。

  • 问题理解 你需要计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。

  • 编辑步骤包括:

    • 增加一个碱基
    • 删除一个碱基
    • 替换一个碱基
  • 数据结构选择 由于我们需要计算最少编辑步骤,动态规划(Dynamic Programming, DP)是一个非常适合的算法。我们可以使用一个二维数组 dp 来存储中间结果,其中 dp[i][j] 表示将 dna1 的前 i 个字符转换成 dna2 的前 j 个字符所需的最少编辑步骤。

  • 算法步骤

  1. 初始化: 如果 dna1 为空,那么将 dna1 转换成 dna2 需要 j 次插入操作。 如果 dna2 为空,那么将 dna1 转换成 dna2 需要 i 次删除操作。
  2. 状态转移: 如果 dna1[i-1] == dna2[j-1],那么 dp[i][j] = dp[i-1][j-1],即不需要任何操作。 否则,dp[i][j] 可以通过以下三种操作中的最小值来得到: 插入:dp[i][j-1] + 1 删除:dp[i-1][j] + 1 替换:dp[i-1][j-1] + 1 最终结果: dp[n][m] 即为将 dna1 转换成 dna2 所需的最少编辑步骤,其中 n 和 m 分别是 dna1 和 dna2 的长度。
  • 个人评价:AI的解法就是官方解法,状态转移方程列的很清晰,很早以前当年第一次刷力扣这道题的时候,它还是困难题~到现在AI都可以轻松解决了,还是简单题哈哈哈。Marscode还是很厉害啊。