25.DNA序列编辑距离
问题描述
小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。
1.思路
1.动态规划算法选择
1.求最小变异次数
2.长度为i-1的DNA序列最小变异次数可推长度i的DNA序列最小变异次数
##### 2.集合选择f[i][j]表示将DNA序列`dna1`的前`i`个字符转换为DNA序列`dna2`的前`j`个字符所需的最小变异次数。
##### 3.集合划分1.当两条DNA序列第i字母相等时,i可划分为A序列为i-1和B序列为j-1时相同+0次变换、A序列为i和B序列为j-1相同+1次变换、A序列为i-1和B序列为j相同+1次变换
2.当两条DNA序列第i字母不相等时,i可划分为A序列为i-1和B序列为j-1时相同+1次变换、A序列为i和B序列为j-1相同+1次变换、A序列为i-1和B序列为j相同+1次变换
2.注意事项
1.初始化
如果dna1是空字符串,那么将其变成dna2所需的变异次数是dna2的长度(因为需要插入每个字符)。
如果dna2是空字符串,那么将其变成dna1的变异次数是dna1的长度(因为需要插入每个字符)。
##### 2.边界问题判断动态规划从`i=1`和`j=1`开始,并且不会访问未定义的索引(如i+1或j+1超出范围)
3.复杂度
双重循环遍历所有的状态,即`i`从`1`到`n`,`j`从`1`到`m`,每个状态计算的复杂度为`O(1)`。因此,填充整个表格的时间复杂度为`O(n × m)`,空间复杂度为'O(nxm)'
代码实现
#include<bits/stdc++.h>
using namespace std;
int solution(std::string dna1, std::string dna2) {
// Please write your code here
int n=dna1.length();
int m=dna2.length();
vector<vector<int>> dp(n+1,vector<int>(m+1));
for(int i =0;i<=n;i++){
for(int j=0;j<=m;j++){
dp[i][j]=n+m;
}
}
for(int i=0;i<=n;i++){
dp[i][0]=i;
}
for(int j=0;j<=m;j++){
dp[0][j]=j;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
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[n][m];
}