最长回文子串及其优化


朴素方法:虽然这种方法做了优化,但时间复杂度超过O(N^2)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define N 110002

char s[N];
int judge(int i,int j)
{
    int len=j-i+1;
    for(int k=0;k<len/2;k++)
        if(s[i+k]!=s[j-k])
        return 0;
    return len;
}
int main()
{
    int i,j;
    while(~scanf("%s",s))
    {
        if(s[0]=='\0')
            continue;
        int len=strlen(s);
        int MAX=1;
        for(i=0;len-i>MAX;i++)
            for(j=len-1;j-i+1>MAX;j--)
            {
                int temp=judge(i,j);
                if(temp>MAX)
                    MAX=temp;
            }
        printf("%d\n",MAX);
    }
    return 0;
}

下面介绍一个时间复杂度为O(n)的算法:manacher 算法

主要利用回文字符串的对称性;有一定的技巧性,自己仔细看代码

可以AC    HDU 3068 最长回文             

耗时: 281MS  时间限制:2s

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 1<<30
#define M 110005
#define kind 26

char str[M],ch[M<<1];
int dp[M<<1];//记录修改后串的单边长度
int solve()
{
    int i,n;//n记录长度
    int ans=1;
    //处理加工成$#a#b#c#0//总个数为奇数个[0,i<<1]
    for(i=1;str[i]!='\0';i++)//这里注意别把"\0" 写成"0"
    {
        ch[i<<1]=str[i];
        ch[(i<<1)+1]='#';
    }
    ch[0]='$';ch[1]='#';
    n=(i<<1);
    ch[n]=0;
    int maxID=0,id=0;
    for(i=1;i<n;i++)
    {
        if(maxID>i)
            dp[i]=min(dp[id*2-i],maxID-i);
        else
            dp[i]=1;
        while(ch[i-dp[i]]==ch[i+dp[i]])
            dp[i]++;
        if(dp[i]+i>maxID)
        {
            maxID=dp[i]+i;
            id=i;
        }
        if(dp[i]>ans)
            ans=dp[i];
    }
    return ans-1;
}
int main()
{
    while(~scanf("%s",&str[1]))
    {
        printf("%d\n",solve());
    }
    return 0;
}

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值