问题描述
小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。
测试样例
样例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
算法设计
-
理解:
我们要把一个DNA序列
dna1变成另一个DNA序列dna2,可以进行的操作有三种:插入、删除和替换。目标是找到最少的操作次数。 -
动态规划:
我们可以用一个二维表格
dp来记录每一步的最优解。dp[i][j]表示将dna1的前i个字符变成dna2的前j个字符所需的最少操作次数。 -
初始化表格:
如果
dna1是空的,那么变成dna2就需要插入dna2的所有字符,所以dp[0][j] = j。 如果dna2是空的,那么变成空字符串就需要删除dna1的所有字符,所以dp[i][0] = i。 -
填充表格:
从
dp[1][1]开始,逐行逐列填充表格。如果
dna1[i-1]和dna2[j-1]相同,那么dp[i][j] = dp[i-1][j-1],因为不需要任何操作。-
如果不同,我们有三种选择:
- 插入:
dp[i][j-1] + 1,表示在dna1的末尾插入一个字符。 - 删除:
dp[i-1][j] + 1,表示删除dna1的最后一个字符。 - 替换:
dp[i-1][j-1] + 1,表示将dna1的最后一个字符替换成dna2的最后一个字符。
- 插入:
-
取这三种操作的最小值作为
dp[i][j]。
-
-
结果:
最终答案就是
dp[m][n],其中m和n分别是dna1和dna2的长度。
关键步骤解释
- 初始化:
dp[i][0]和dp[0][j]的初始化是为了处理边界情况,即一个字符串为空的情况。 - 状态转移:通过比较
dna1[i-1]和dna2[j-1],决定是否需要编辑操作,并选择最小的编辑步骤。
总结
- 这个算法的核心是用动态规划来记录每一步的最优解,通过比较字符来决定下一步的操作。
- 初始化表格是为了处理边界情况,填充表格则是通过比较字符来决定最小的操作次数。
- 最后返回表格的最后一个值,就是我们需要的最少编辑步骤