牛客——最长子字符串

1. 02最长子字符串

题目

牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度。
例如:A = 4 B = 0 K = 30000 -> 1110 -> 1001 -> 0100 -> 1111

思路

动态规划。

两个字符串从1增长到各自的长度。
memo[i][j]中记录着,两个字符串分别为i,j时的子字符串长度。
如果某个下标对应字符相同,那么memo[i][j]等于其memo[i-1][j-1]+1,也就是斜上一个+1。
否则,选取上面和前面中最大的(因为这两个能增加到当前两个字符串,如果不同必然和上一个字符串的最长子字符串长度相同)。

#include 
#include 
#include 
#include 
using namespace std;

string commonStr(string &l,string &r)
{
    int llen=l.size();
    int rlen=r.size();
    //memo[i][j]中存储的是:第一个字符串长i,第二个长j时
    //最长公共子字符串。
    vector> memo(llen+1,vector(rlen+1,0));
    vector> memoPath(llen+1,vector(rlen,0));
    
    memo[0][0]=0;
    
    for(int li = 1;li<=llen;li++)
    {
        for(int ri = 1;ri<=rlen;ri++)
        {
            //当某个字符相等时,标记字符串长度比之前的+1;
            if(l[li-1]==r[ri-1])
            {
                memo[li][ri]=memo[li-1][ri-1]+1;
                memoPath[li][ri]=1;
            //当不同时,选取,能够达到ij长度的两条子字符串的最长长度
            //(i-1)j和i(j-1)这两条字符串能够到达ij
            }else if(memo[li][ri-1]>memo[li-1][ri]){
                memo[li][ri]=memo[li][ri-1];
                memoPath[li][ri]=2;
            }else{
                memo[li][ri]=memo[li-1][ri];
                memoPath[li][ri]=3;
            }
        }
    }

    for(auto i:memo)
    {
        cout<0 && pathR>0)
    {
        if(memoPath[pathL][pathR] == 1)
        {
            s.push_back(l[pathL-1]);
            pathL--;
            pathR--;
        }else if(memoPath[pathL][pathR] == 2)
        {
            pathR--;
        }else{
            pathL--;
        }
    }
    reverse(s.begin(),s.end());

    cout<>l>>r;
    // l="bdcaba";
    // r="abcbdab";
    cout<<"result: "<

你可能感兴趣的:(牛客——最长子字符串)