最长回文子串

[i,j]是回文串 若 str[i-1]==str[j+1]则 [i-1,j+1]也是回文串。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<stack>
#include<list>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;

int Max(int a,int b)
{
    return a>b?a:b;
}

char str[1111111];
int dp[5555][5555];
int main()
{
    int n;
    while(~scanf("%d",&n)!=EOF){
        for(int k=0;k<n;k++){
            int ans=0;
            scanf("%s",str+1);
            memset(dp,0,sizeof(dp));
            for(int i=1;str[i];i++){
                dp[i][i]=1;
                if(str[i]==str[i+1])
                    dp[i][i+1]=1;
            }
            int len=0;
            for(int i=1;str[i];i++)
                len++;
            for(int i=1;i<=len;i++){
                for(int j=1;j+i<=len;j++){
                    int cc=i+j;
                    if(str[j]==str[cc])
                        if(dp[j+1][cc-1]) dp[j][cc]=1;
                    if(dp[j][cc]) ans=Max(ans,i+1);
                  //  printf("%d %d %d",i,i+j,dp[i][j+i]);system("pause");
                }
            }
            printf("%d
",ans);
        }
    }
    return 0;
}

  从中间向两边跑

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<stack>
#include<list>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include <fstream>
using namespace std;

string expand(string s1,int a,int b)
{
    int l=a;int r=b;
    int len=s1.length();
    while(l>=0&&r<len&&s1[l]==s1[r]){
        l--;r++;
    }
    return s1.substr(l+1,r-l-1);
}

string Max(string a,string b)
{
    if(a.length()>b.length())
        return a;
    else
        return b;
}
string str;
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int k=0;k<n;k++){
            cin>>str;
            string longest = str.substr(0,1);
            int len=str.length();
            for(int i=0;i<len;i++){
                longest=Max(longest,expand(str,i,i));
              //  printf("%d ",i);
              //  cout<<longest<<endl;
              //  system("pause");
            }
            for(int i=0;i<len;i++){
                if(str[i]==str[i+1])
                    longest=Max(longest,expand(str,i,i+1));
            }
            printf("%d
",longest.length());
        }
    }
    return 0;
}

  O(n)的算法。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<stack>
#include<list>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include <fstream>
using namespace std;
int Min(int a,int b)
{
    return a>b?b:a;
}
int p[1111111];
char str[1111111],s1[1111111];
int len;
void pk()
{
    int mx=0;int id;
    for(int i=1;i<len;i++){
        if(mx>i){
            p[i]=Min(p[id*2-i],mx-i);
        }
        else
            p[i]=1;
        for(;s1[i-p[i]]==s1[i+p[i]];p[i]++);
        if(p[i]+i>mx){
            mx=p[i]+i;
            id=i;
        }
    }
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
    for(int i=0;i<n;i++){
        scanf("%s",str);
        s1[0]='.';
        s1[1]='#';
        len=strlen(str);
        for(int j=0;j<len;j++){
            s1[2*j+2]=str[j];
            s1[2*j+3]='#';
        }
        len=len*2+1;
        int ans=0;
        pk();
        for(int i=1;i<len;i++)
            if(ans<p[i]) ans=p[i];
        printf("%d
",ans-1);
    }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/yigexigua/p/3845169.html