编辑距离

编辑距离是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。


设dp[i][j]表示str1的0到i位置的子串转换成str2的0到j位置的子串所需的最小编辑距离,则有
dp[i, j] := minimum(
dp[i-1, j] + 1, //在str1上i位置删除字符(或者在str2上j-1位置插入字符)
dp[i, j-1] + 1, //在str1上i-1位置插入字符(或者在str2上j位置删除字符)
dp[i-1, j-1] + cost // 替换操作
很容易就能写出动规代码:

时间复杂度O(m*n),空间复杂度O(m*n)

class Solution {  
public:  
    int minDistance(string word1, string word2) {  
          
        int m=word1.size();  
        int n=word2.size();  
        vector<vector<int>> dis(m+1);  
        for(int i=0;i<=m;i++)dis[i].assign(n+1,INT_MAX);  
          
        dis[0][0]=0;  
        for(int i=0;i<=m;i++)  
        for(int j=0;j<=n;j++){  
            if(i>0) dis[i][j] = min(dis[i][j],dis[i-1][j]+1); //delete    
            if(j>0) dis[i][j] = min(dis[i][j],dis[i][j-1]+1);//insert    
    
            //substitute    
            if(i>0&&j>0)    
            {    
                if(word1[i-1]!=word2[j-1])    
                    dis[i][j] = min(dis[i][j],dis[i-1][j-1]+1);    
                else    
                    dis[i][j] = min(dis[i][j],dis[i-1][j-1]);    
            }    
        }  
        return dis[m][n];  
    }  
};  

将空间进行优化,注意到dp[i][j]只与dp[i-1][j],dp[i-1][j-1],dp[i][j-1]有关,所以可以将二维数组变成一维数组来处理,即滚动数组

class Solution {  
public:  
    int minDistance(string word1, string word2) {  
          
        int f[word2.length()+1];  
        int upper_left=0;//记录f[i-1][j-1];  
        for(size_t i=0;i<=word2.size();++i)  
            f[i]=i;  
        for(size_t i=1;i<=word1.size();++i){  
            upper_left=f[0];  
            f[0]=i;  
              
            for(size_t j=1;j<=word2.size();++j){  
                int upper=f[j];  
                  
                if(word1[i-1]==word2[j-1])  
                    f[j]=upper_left;  
                else  
                    f[j]=1+min(upper_left,min(f[j],f[j-1]));  //f[j-1]表示dp[i][j-1],f[j]表示dp[i][j]
                upper_left=upper;  
            }  
        }  
          
        return f[word2.length()];  
    }  
};  

还有一类问题也属于编辑距离问题,即用于DNA的比对问题:

问题描述:

DNA在复制的时候可能出现的偏差是(理论上,对每个碱基被复制时,都可能出现偏差):

 1. 漏掉某个脱氧核苷酸。例如把 AGGT 复制成为:AGT

    2. 错码,例如把 AGGT 复制成了:AGCT

    3. 重码,例如把 AGGT 复制成了:AAGGT

    如果某DNA串a,最少要经过 n 次出错,才能变为DNA串b,则称这两个DNA串的距离为 n。


    例如:AGGTCATATTCC 与 CGGTCATATTC 的距离为 2


这其实也就是编辑距离的变形,代码同上


你可能感兴趣的:(动态规划)