LeetCode-5. 最長迴文子串(Manacher)

kewlgrl發表於2018-05-01

5. 最長迴文子串


給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 的最大長度為1000。

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba"也是一個有效答案。

示例 2:

輸入: "cbbd"
輸出: "bb"

C




#include<bits/stdc++.h>
using namespace std;
/********************提交程式碼********************/
char* longestPalindrome(char* s)
{
    int i,n=0,len=strlen(s);
    char *str=(char*)malloc((3*len)*sizeof(char));
    int *p=(int*)malloc((3*len)*sizeof(int));
    str[n++]='$';//加入字串首部的字串
    for(i=0; s[i]; i++)
    {
        str[n++]='#';
        str[n++]=s[i];
    }
    str[n++]='#';
    str[n]='\0';
    int mx=0,id,pos=0,r=0,val=0;;
    p[0]=0;
    for(i=1; i<n; i++)
    {
        if(mx>i)
            if(p[2*id-i]<mx-i)//p[i]表示i處的迴文長度
                p[i]=p[2*id-i];
            else
                p[i]=mx-i;
        else//如果i大於mx,則必須重新自己算
            p[i]=1;
        while(str[i-p[i]]==str[i+p[i]])//迴文串的半徑
            p[i]++;
        if(p[i]+i>mx)//記錄目前回文字串擴充套件最長的id
        {
            mx=p[i]+i;
            id=i;
        }
        if(p[i]>r)
            r=p[i],pos=i;
    }
    int cnt=0;
    val=(r-1);//最長迴文串的長度
    pos/=2;//迴文串中心位置
    char *ans=(char*)malloc((val+1)*sizeof(char));
    if(val%2)
        for(i=pos-val/2-1; i<pos+val/2; ++i)
            ans[cnt++]=s[i];
    else
        for(i=pos-val/2; i<pos+val/2; ++i)
            ans[cnt++]=s[i];
    ans[cnt]='\0';//不加結束符在OJ上會有多餘輸出
    return ans;
}
/***************************************************/
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("F:/cb/read.txt","r",stdin);
    //freopen("F:/cb/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    char s[1000];
    while(cin.getline(s,1000))
    {
        cout<<"/"<<longestPalindrome(s)<<"/"<<endl;
    }
    return 0;
}


最慘的是因為ans結尾沒加\0在OJ上結尾會有多餘輸出卡了好久……┭┮﹏┭┮

Manacher-求最長迴文字串 基本就是這個程式碼改的,On的複雜度。

輸出是擷取字串起始位置是:中心點座標-最大長度/2

相關文章