zoukankan      html  css  js  c++  java
  • [DP]最长公共子串

    题目

    给定两个字符串str1和str2, 长度分别稳M和N,返回两个字符串的最长公共子串

    解法一

    这是一道经典的动态规划题,可以用M*N的二维dp数组求解.dp[i][j]代表以str1[i]和str2[j]当做公共子串结尾的情况下,公共子串能有多长.然后分析可以发现dp[i][j]只与dp[i- 1][j - 1]有关:当str1[i] 和str2[j]相等的时候, dp[i][j] = dp[i - 1][j - 1] + 1;当它们不相等的时候,dp[i][j] = 0.获得dp数组之后要获得最长公共子串只需要找到数组中最大的值,其值代表最长子串的长度,其所在的索引代表了子串在原字符串中结束的位置.

    代码

    先获取dp数组,然后通过dp数组得到最长公共子串

    //最长公共子串的dp数组
    vector<vector<int> > getdp1(string str1, string str2) {
        vector<vector<int> > dp(str1.length(), vector<int>(str2.length()));
        if (str1.length() == 0 || str2.length() == 0)
            return dp;
        dp[0][0] = str1[0] == str2[0] ? 1 : 0;
        for (int i = 1; i < int(str1.length()); i ++)
            dp[i][0] = str1[i] == str2[0] ? 1 : 0;
        for (int j = 1; j < int(str2.length()); j ++)
            dp[0][j] = str2[j] == str1[0] ? 1 : 0;
    
        for (int i = 1; i < int(str1.length()); i ++) {
            for (int j = 1; j < int(str2.length()); j ++) {
                if (str1[i] == str2[j])
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = 0;
            }
        }
        return dp;
    }
    
    // 最长公共子串的解法一
    string lcst1(string str1, string str2) {
        string res = "";
        if (int(str1.length()) == 0 || int(str2.length()) == 0)
            return res;
        vector<vector<int> > dp = getdp1(str1, str2);
        int maxNum = 0;
        int maxIndex;
        for (int i = 0; i < int(dp.size()); i ++) { // 遍历dp矩阵找到最大值
            for (int j = 0; j < int(dp[0].size()); j ++)
                if (dp[i][j] > maxNum) {
                    maxNum = dp[i][j];
                    maxIndex = i;
                }
        }
    
        res = str1.substr(maxIndex - maxNum + 1, maxNum);
        return res;
    }
    

    解法二

    上面这种解法需要的时间复杂度和空间复杂度都是O(M* N).下面提供一种空间复杂度为O(1)的解法

    代码

    //最长公共子串解法二
    string lcst2(string str1, string str2) {
        string res = "";
        if (int(str1.length()) == 0 || int(str2.length()) == 0)
            return res;
    
        int maxNum = 0; //记录最大值
        int maxindex = -1; //记录最大值的索引
        int tmpNum; //记录当前值,如果大于最大值就更新
        int i = int(str1.length()) - 1;
        int j = int(str2.length()) - 1;
        for (j; j >= 0; j --) { // 斜线先向左移动
            tmpNum = 0;
            for (int tmp = 0; tmp < int(str2.length()) - j; tmp ++){
                if (str1[tmp] == str2[j + tmp]) {
                    tmpNum = tmpNum == 0 ? 1 : tmpNum + 1;
                } else
                    tmpNum = 0;
                if (tmpNum > maxNum) {
                    maxNum = tmpNum;
                    maxindex = j + tmp;
                }
            }
        }
    
        bool triangleUpFlag = true; //maxindex 在通过斜线计算的时候属于上三角的flag
        for (i; i > 0; i --) { //列移到最左边之后再向下移动
            tmpNum = 0;
            for (int tmp = 0; tmp < int(str1.length()) - i; tmp ++) {
                if (str2[tmp] == str1[i + tmp])
                    tmpNum = tmpNum == 0 ? 1 : tmpNum + 1;
                else
                    tmpNum == 0;
                if (tmpNum > maxNum) {
                    maxNum = tmpNum;
                    triangleUpFlag = false;
                    maxindex = i + tmp;
                }
            }
        }
    
        cout<<maxindex<<" "<<maxNum<<" "<<triangleUpFlag<<endl;
        res = triangleUpFlag == true ? str2.substr(maxindex - maxNum + 1, maxNum) : str1.substr(maxindex - maxNum + 1, maxNum);
        return res;
    }
    
    int main()
    {
        string str1 = "1AB2345CD";
        string str2 = "12345EF";
        //string str1 = "abcde";
        //string str2 = "bebcd";
        cout<<lcst2(str1, str2)<<endl; //输出2345
        return 0;
    }
    
  • 相关阅读:
    Eclipse安装Hadoop插件
    (转)Ubuntu14.0.4中hadoop2.4.0伪分布模式配置
    Hadoop--DataNode无法启动
    启动与关闭hadoop
    hadoop中执行命令时发生错误
    strings命令
    Deriving data from ElasticSearch Engine
    elasticsearch data importing
    reading words in your computer and changing to female voice, linux festival text2wave saving wav files
    DDNS client on a Linux machine
  • 原文地址:https://www.cnblogs.com/mooba/p/7473553.html
Copyright © 2011-2022 走看看