青训营X豆包MarsCode 技术训练营第三课 | 豆包MarsCode AI 刷题

34 阅读3分钟

程序解析

这段代码实现了计算两个DNA序列之间的**编辑距离(Levenshtein Distance)**的功能。编辑距离是指通过插入、删除或替换操作,将一个字符串转换为另一个字符串所需的最小操作数。

代码分析

  1. 函数定义:

    python
    def solution(dna1, dna2):  
    
    • dna1:第一个DNA序列字符串。
    • dna2:第二个DNA序列字符串。
  2. 初始化:

    python
    m = len(dna1)  
    n = len(dna2)  
    dp = [[0] * (n + 1) for _ in range(m + 1)]  
    
    • m:第一个DNA序列的长度。
    • n:第二个DNA序列的长度。
    • dp:创建一个大小为 (m+1) x (n+1) 的二维列表,用于保存编辑距离的动态规划表。
  3. 填充第一行和第一列:

    python
    for i in range(m + 1):  
        dp[i][0] = i  # 从dna1到空字符串的操作数为i(删除操作)  
    for j in range(n + 1):  
        dp[0][j] = j  # 从空字符串到dna2的操作数为j(插入操作)  
    
    • 第一列 dp[i][0] 初始化为 i,表示将 dna1 的前 i 个字符全部删除的操作步骤。
    • 第一行 dp[0][j] 初始化为 j,表示将空字符串转换为 dna2 的前 j 个字符的插入步骤。
  4. 填充DP表:

    python
    for i in range(1, m + 1):  
        for j in range(1, n + 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)  # 替换操作  
    
    • 双重循环遍历每一个字符对,如果当前字符相同,则不需要任何操作,直接取上一个状态的值。
    • 如果字符不同,计算三种操作的最小值:删除、插入和替换,并将结果存储在 dp[i][j] 中。
  5. 返回结果:

    python
    return dp[m][n]  # 返回最终的编辑距离  
    
    • 返回最终编辑距离,即将 dna1 转换为 dna2 所需的最小操作数。

示例运行

在代码示例中:

python
if __name__ == "__main__":  
    print(solution("AGCTTAGC", "AGCTAGCT") == 2)  # 应返回 True,表示编辑距离正确  
    print(solution("AGCCGAGC", "GCTAGCT") == 4)    # 应返回 True,表示编辑距离正确  

总结与应用

  1. 时间复杂度

    • 该算法的时间复杂度为 O(m * n),其中 m 和 n 分别是两个字符串的长度。每个字符都会在动态规划表中被计算一次。
  2. 空间复杂度

    • 空间复杂度为 O(m * n),用于存储动态规划表的条件。
  3. 应用

    • 编辑距离常用于文本比对、拼写检查、基因序列比对、自然语言处理等领域。

建议改进

  • 空间优化:可以考虑使用一维数组来存储当前和前一行的状态,以节省空间。例如,只需要保留前一行的计算结果即可。
  • 更多测试案例:可以加入更多不同长度和内容的DNA序列,以验证算法的准确性和鲁棒性