DNA序列编辑距离
原题链接:DNA序列编辑距离 - MarsCode
问题描述
小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[i][j]表示为dna1的前i个字母变为dna2的前j个字母的集合,其值为集合中变换次数最少的数值。
状态计算:
若dna1的第i个字母等于dna2的第j个字母,说明当前字母不需要变换,所以dna1的前i字母变为dna2的前j字母次数等于dna1的前i-1字母变为dna2的前j-1字母次数,即:dp[i][j]=dp[i-1][j-1];
若dna1的第i个字母不等于dna2的第j个字母,考虑“最后一步”,即将第i个字母修改为第j个字母、删除第i个字母和增加第j个字母,即:dp[i][j]=min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1)(对应改、删、增)
注意:当i等于0(或者j等于0)时,只能插入(或删除)操作,且插入(删除)次数等于另一个dna链的长度。即需要初始化dp数组。
def solution(dna1, dna2):
# 注意初始化列数至少等于dna2的长度+1 行数至少等于dna1的长度+1
dp = [[0]*(len(dna2)+10) for i in range(len(dna1)+10)]
# dna1的空链变为dna2链前i个字母的插入次数
for i in range(len(dna2)+1):
dp[0][i]=i
# dna1的前j个字母变为空链的删除次数
for j in range(len(dna1)+1):
dp[j][0]=j
for i in range(1,len(dna1)+1):
for j in range(1,len(dna2)+1):
if dna1[i-1]==dna2[j-1]:
dp[i][j]=dp[i-1][j-1]
else:
dp[i][j]=dp[i-1][j-1]+1
dp[i][j]=min(dp[i][j],dp[i-1][j]+1)
dp[i][j]=min(dp[i][j],dp[i][j-1]+1)
return dp[len(dna1)][len(dna2)]
int solution(string dna1, string dna2)
{
int n = dna1.size(), m = dna2.size();
vector<vector<int>> dp(n + 1, vector<int>(m + 1));
// dna1空链变dna2的前j子串
for (int j = 0; j <= m; ++j)
dp[0][j] = j;
// dna1前i子串变空链
for (int i = 0; i <= n; ++i)
dp[i][0] = i;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (dna1[i] == dna2[j])
{
dp[i][j] = dp[i - 1][j - 1];
}
else
{
dp[i][j] = dp[i - 1][j - 1] + 1;
dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1);
dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1);
}
}
}
return dp[n][m];
}
知识总结
此题主要考察动态规划,难点在于定义状态。动态规划的状态定义难以捉摸,只能靠刷题数量进行堆积,只要看多了状态定义,则很容易套出来。
学习计划
我也只是一名刚学习算法的新手。之前学习动态规划的时候总是抓不住点,题解步骤是什么等。如今,我初探动态规划,我认为动态规划主要步骤就两个:状态表示和状态计算,难点也是这两个,状态表示需要多刷题,状态计算抓住”最后一步“进行解题。对于制定学习计划,若是刚学或未学动态规划,则需先弄懂动态规划的模板题,如:背包问题、线性DP等。模板题全弄懂,那就可以针对每个模板进行扩展,可以在掘金上的AI刷题中动态规划分类中刷题,若遇到找不到思路的题目,还可问MarsCode AI,非常方便。学习效率也更高效。当然遇到错题一定要整理,过段时间就看下错题,说不定就探索出通用解法了呢。
工具运用
目前我用AI 刷题功能的时间也不多,但也知道了几点可以增加我们学习效率的方法。首先就是MarsCode AI,当没有解题思路时,使用刷题页面旁边的MarsCode AI给出解题思路,就可以很快的给出一个解题思路,并且大多数是正确的。其次使用AI 刷题可以选择某些具体算法并有难度区分,可以阶梯式的学习算法等。