Likou5。最長の回文部分文字列dp馬車アルゴリズム

https://leetcode-cn.com/problems/longest-palindromic-substring/ここに画像の説明を挿入します
アイデア1:dp dpd p、ifs [i…j] s [i…j]s [ ij ]は回文であり、dp [i] [j] = 1 dp [i] [j] = 1d p [ i ] [ j ]=1、それ以外の場合はdp [i] [j] = 0 dp [i] [j] = 0d p [ i ] [ j ]=0、再然dp [i] [i] = 1 dp [i] [i] = 1d p [ i ] [ i ]=1、次の列挙間隔の長さlen lenL E Nと点出発IIをiの場合、終点はj = i + len − 1 j = i + len-1です。j=+l e n1s [i] = s [j] s [i] = s [j]である限りs [ i ]=s [ j ] ANDdp[i + 1] [j − 1] = 1 dp [i + 1] [j-1] = 1d p [ i+1 ] [ j1 ]=1s [i…j] s [i…j]を意味しますs [ ij ]は回文文字列であり、複雑さはO(n 2)O(n ^ 2)です。O n2

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        int n=s.size();
        vector<vector<bool>> dp(n,vector<bool>(n));
        int start=0,maxlen=1;
        dp[0][0]=1;
        for(int i=1;i<n;i++)
        {
    
    
            dp[i][i]=1;
            if(s[i]==s[i-1])
            {
    
    
                dp[i-1][i]=1;
                start=i-1;
                maxlen=2;
            }
        }
        for(int len=3;len<=n;len++)
        {
    
    
            for(int i=0;i+len-1<n;i++)
            {
    
    
                int j=i+len-1;
                if(s[i]==s[j]&&dp[i+1][j-1])
                {
    
    
                    dp[i][j]=1;
                    if(j-i+1>maxlen)
                        maxlen=j-i+1,start=i;
                }
            }
        }
        return s.substr(start,maxlen);
    }
};

アイデア2:回文ストリングの性質を考慮して、中間点から両側に拡張して、ストリングが回文ストリングであるかどうかを判断し、nnの長さで決定することができます。nの文字列の場合、中間点の合計は2 ∗ n − 1 2 * n-1になります。2n具体的には、 1つの選択肢:1。1。1 中心のような特定の文字、NNn種類の選択肢;2.2。2 ある中心として隣接する二つの文字の中間にN - 1、N-1n1つの選択肢。列挙するだけで、複雑さはO(n 2)O(n ^ 2)です。O n2

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        int n=s.size();
        int start=0,maxlen=1;
        for(int i=0;i<n;i++)
        {
    
    
            int tmp=calLen(s,i,i);
            if(tmp>maxlen)
                maxlen=tmp,start=i-(tmp>>1);
            tmp=calLen(s,i,i+1);
            if(tmp>maxlen)
                maxlen=tmp,start=i-(tmp>>1)+1;
        }
        return s.substr(start,maxlen);
    }

    int calLen(const string &s,int l,int r)
    {
    
    
        int ml=0,mr=s.size()-1;
        while(l>=ml&&r<=mr&&s[l]==s[r])
            --l,++r;
        return r-l-1;
    }
};

アイデア3:馬車アルゴリズム記事を参照してください

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        string t="#";
        int n=s.size();
        for(int i=0;i<n;i++)
        {
    
    
            t+=s[i];
            t+="#";
        }
        n<<=1;
        vector<int> len(n+1);
        int l=0,r=-1,k;
        int start=0,maxlen=1;
        for(int i=0;i<=n;i++)
        {
    
    
            k=i>=r?1:min(len[l+r-i],r-i);
            while(0<=i-k&&i+k<=n&&t[i-k]==t[i+k])
                ++k;
            len[i]=--k;
            if(i+k>r)
                l=i-k,r=i+k;
            if(len[i]>maxlen)
            {
    
    
                maxlen=len[i];
                start=(i-maxlen)>>1;
            }
        }
        return s.substr(start,maxlen);
    }
};

おすすめ

転載: blog.csdn.net/xiji333/article/details/114484210