lintcode 77.Longest Common Subsequence(最长公共子序列)、79. Longest Common Substring(最长公共子串)

Longest Common Subsequence最长公共子序列:

每个dp位置表示的是第i、j个字母的最长公共子序列

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int len1 = A.size();
        int len2 = B.size();
        if(len1 == 0 || len2 == 0)
            return 0;
        
        vector<vector<int>> result(len1+1,vector<int>(len2+1));
        for(int i = 0;i <= len1;i++){          //第一行第一列都为0,因为第一行第一列都没有字符串
            result[i][0] = 0;
        }
        for(int i = 0;i <= len2;i++){
            result[0][i] = 0;
        }
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(A[i-1] == B[j-1])
                    result[i][j] = result[i-1][j-1] + 1;
                else
                    result[i][j] = max(result[i-1][j],result[i][j-1]);
            }
        }
        return result[len1][len2];
    }
};

Longest Common Substring最长公共子串

每个dp代表以i、j这个坐标的最长公共子串,所以求最终的要遍历所有的

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int len1 = A.size();
        int len2 = B.size();
        if(len1 == 0 || len2 == 0)
            return 0;
        
        vector<vector<int>> result(len1+1,vector<int>(len2+1));
        for(int i = 0;i <= len1;i++){            //第一行第一列都为0
            result[i][0] = 0;
        }
        for(int i = 0;i <= len2;i++){
            result[0][i] = 0;
        }
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(A[i-1] == B[j-1])
                    result[i][j] = result[i-1][j-1] + 1;
                else
                    result[i][j] = 0;
            }
        }
        int maxnum = 0x80000000;
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(result[i][j] > maxnum)
                    maxnum = result[i][j];
            }
        }
        return maxnum;
    }
};

更简洁的一种写法:

class Solution {
public:
    /**
     * @param A: A string
     * @param B: A string
     * @return: the length of the longest common substring.
     */
    int longestCommonSubstring(string &A, string &B) {
        // write your code here
        int m = A.size();
        int n = B.size();
        vector<vector<int> > dp(m+1,vector<int>(n+1));
        for(int i = 0;i <= m;i++)
            dp[i][0] = 0;
        for(int i = 0;i <= n;i++)
            dp[0][i] = 0;
        int max_num = 0;
        for(int i = 1;i <= m;i++){
            for(int j = 1;j <= n;j++){
                if(A[i-1] == B[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                    max_num = max(max_num,dp[i][j]);
                }
                else
                    dp[i][j] = 0;
            }
        }
        return max_num;
    }
};

 

 

相同:都要建立m+1,n+1的二维数组

区别:1. 最长公共子串要求连续的,最长公共子序列可以不连续,所以dp的递推公式第二项不同

   2. 最长公共子序列最后一个值就是最长,最长公共子串要比较哪个位置最长

posted @ 2018-06-07 22:34  有梦就要去实现他  阅读(164)  评论(0编辑  收藏  举报