双字符串DP小结

本文总结一下一些双字符串的DP问题。具体解法是要建立以两个字符串为边的矩阵。

vector> dp(lenA+1, vector(lenB+1, 0)); \\ 要加1

dp[i][j] 为以A[i]结尾,和B[j]结尾的满足条件解。

    0 a b c d
0   
a
c
m
n

Longest Common Sub-sequence:

这道题的点是sub-sequence可以不连续。
dp[i][j] = 以A[i], B[j]为结尾,的最长sub-sequence长度。通项公式为

if(A[i] == B[j]) dp[i][j] = dp[i-1][j-1]+1;
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
int longestRepeatingSubsequence(string& str) {
        // Write your code here
        int len = str.length();
        vector> dp(len+1, vector(len+1, 0));
        for(int i=1; i<=len; i++){
            for(int j=1; j<=len; j++){
                if(str[i-1] == str[j-1] && i != j){
                    dp[i][j] = 1 + dp[i-1][j-1];
                }else{
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return dp[len][len];
    }

Longest Common Substring:

这道题要点是sub-string必须连续,
dp[i][j] = 以A[i], B[j]为结尾,的最长sub-string长度 (必须包含A[i], B[j])。通项公式为:

if(A[i] == B[j]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = 0;

然后新添一个max_len变量,打擂台, 找最长。

int longestCommonSubstring(string &A, string &B) {
        // write your code here
        if(A.empty() || B.empty()) return 0;
        int lenA = A.size(), lenB = B.size();
        vector> dp(lenA+1, vector(lenB+1, 0));
        int max_len = 0;
        for(int i=1; i<=lenA; i++){
            for(int j=1; j<=lenB; j++){
                if(A[i-1] == B[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }else{
                    dp[i][j] = 0;
                }
                if(dp[i][j] > max_len) max_len = dp[i][j];
            }
        }
        return max_len;
    }

Edit Distance

这道题的要点是下面的表达式。表示新加一个,删除一个,和edit一个。
dp[i][j]为以A[i], B[j]为结尾的最短edit distance。通项公式为:

dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
 int minDistance(string word1, string word2) {
        // write your code here
        if(word1.empty()) return word2.length();
        else if(word2.empty()) return word1.length();
        int lenA = word1.length(), lenB = word2.length();
        vector> dp(lenA+1, vector(lenB+1, 0));
        for(int i=0; i<=lenA; i++){
            dp[i][0] = i;
        }
        for(int i=0; i<=lenB; i++){
            dp[0][i] = i;
        }
        for(int i=1; i<=lenA; i++){
            for(int j=1; j<=lenB; j++){
                if(word1[i-1] == word2[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
                }
            }
        }
        return dp[lenA][lenB];
    }

你可能感兴趣的:(双字符串DP小结)