计算DNA序列的最少编辑步骤

62 阅读3分钟

问题描述

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

测试样例

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

    • 输出:1
  • 输入:dna1 = "AACCGGTT", dna2 = "AACCTTGG"

    • 输出:4
  • 输入:dna1 = "ACGT", dna2 = "TGC"

    • 输出:3
  • 输入:dna1 = "A", dna2 = "T"

    • 输出:1
  • 输入:dna1 = "GGGG", dna2 = "TTTT"

    • 输出:4

思路

  1. 定义状态:使用一个二维数组 dp,其中 dp[i][j] 表示将 dna1 的前 i 个字符转换为 dna2 的前 j 个字符所需的最少编辑步骤。

  2. 初始化

    • dp[0][j] 表示将空字符串转换为 dna2 的前 j 个字符,显然需要 j 次插入操作。
    • dp[i][0] 表示将 dna1 的前 i 个字符转换为空字符串,显然需要 i 次删除操作。
  3. 状态转移

    • 如果 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[i][j]

  4. 最终结果dp[m][n] 即为将 dna1 转换为 dna2 所需的最少编辑步骤,其中 m 和 n 分别是 dna1 和 dna2 的长度。

代码详解

public class Main { public static int solution(String dna1, String dna2) { int m = dna1.length(); int n = dna2.length();

    // 创建一个二维数组 dp
    int[][] dp = new int[m + 1][n + 1];
    
    // 初始化 dp 数组
    for (int i = 0; i <= m; i++) {
        dp[i][0] = i;
    }
    for (int j = 0; j <= n; j++) {
        dp[0][j] = j;
    }
    
    // 填充 dp 数组
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (dna1.charAt(i - 1) == dna2.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1;
            }
        }
    }
    
    // 返回最终结果
    return dp[m][n];
}

public static void main(String[] args) {
    // 你可以添加更多测试用例
    System.out.println(solution("AGCTTAGC", "AGCTAGCT") == 2);
    System.out.println(solution("AGCCGAGC", "GCTAGCT") == 4);
}
}

知识总结

新知识点

  1. 动态规划:通过定义状态、初始化、状态转移和最终结果,解决编辑距离问题。
  2. 二维数组:使用二维数组来存储中间状态,便于计算和更新。
  3. 字符串操作:理解字符串的插入、删除和替换操作,并将其转化为动态规划的状态转移。

学习建议

  • 理解动态规划:动态规划是解决复杂问题的有效方法,建议多练习类似的题目,加深对状态定义和状态转移的理解。
  • 多做练习:通过刷题巩固知识点,特别是动态规划相关的题目,可以提高解题能力。
  • 总结经验:每次刷题后,总结解题思路和方法,形成自己的解题模板。