AI刷题 25.DNA序列编辑距离 | 豆包MarsCode AI刷题

35 阅读2分钟

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];
}