DNA序列编辑距离
问题描述
小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
解题思路
此代码片段实现了计算两个字符串之间最小编辑距离的动态规划算法。编辑距离是指将一个字符串转换为另一个字符串所需的最少单字符编辑操作数(插入、删除或替换)。
- 定义状态:我们定义一个二维数组
dp,其中dp[i][j]表示将字符串dna1的前i个字符转换为字符串dna2的前j个字符所需的最小编辑距离。 - 初始化边界条件:当其中一个字符串为空时,最小编辑距离就是另一个字符串的长度。因此,
dp[i][0]初始化为i,表示从dna1的前i个字符到空串的编辑距离;dp[0][j]初始化为j,表示从空串到dna2的前j个字符的编辑距离。 - 状态转移:对于
dna1和dna2中的每个字符,我们检查它们是否相等。如果相等,则不需要编辑,dp[i][j]等于dp[i-1][j-1]。如果不相等,我们需要进行编辑操作,选择插入、删除或替换操作中代价最小的那个,并在此基础上加1。 - 计算最小编辑距离:通过上述步骤填充
dp数组后,dp[m][n]即为我们所求的最小编辑距离,其中m和n分别是两个字符串的长度。
这个算法的时间复杂度为O(mn),空间复杂度也是O(mn),因为它需要存储一个大小为(m+1)*(n+1)的二维数组。在实际应用中,这个算法可以用于文本比较、拼写检查、生物信息学中的序列比对等领域。
最终代码
m = len(dna1)
n = len(dna2)
# 初始化dp数组,大小为 (m+1) x (n+1)
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 初始化边界条件
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数组
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:
# 否则,我们选择插入、删除或替换操作的最小值加1
dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1
# 返回最终结果,即从dna1到dna2的最小编辑距离
return dp[m][n]
# 测试样例
print(solution("AGCTTAGC", "AGCTAGCT") == 2)
print(solution("AGCCGAGC", "GCTAGCT") == 4)
print(solution("AGT", "AGCT") == 1)
print(solution("AACCGGTT", "AACCTTGG") == 4)
print(solution("ACGT", "TGC") == 3)
print(solution("A", "T") == 1)
print(solution("GGGG", "TTTT") == 4)
总结
这段代码实现了计算两个字符串之间最小编辑距离的动态规划算法。它通过构建一个二维数组来逐步计算子问题的解,并最终得到整个问题的解。该算法的时间复杂度为O(m*n),其中m和n分别是两个字符串的长度。这种方法在字符串处理、自然语言处理等领域有着广泛的应用。