最长子回文串

本文介绍了一种解决最长回文子串问题的高效算法,通过中心扩展法实现O(N)的时间复杂度,并提供了详细的代码解析及注释,有助于读者深入理解算法原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

#1032 : 最长回文子串

时间限制: 1000ms
单点时限: 1000ms
内存限制: 64MB

描述

   小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

   这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

   小Ho奇怪的问道:“什么叫做最长回文子串呢?”

   小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

   小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

   小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

它给的提示是要用中心往两边扩展的方法,但是还是超时。

所以只能用时间复杂度最小的O(N);

#include<vector>
#include<iostream>
using namespace std;
#include<cstring>
const int N=1000001;
int n, p[N];
char s[N], str[N];

#define _min(x, y) ((x)<(y)?(x):(y))

void kp()
{
    int i;
    int mx = 0;
    int id;
    for(i=n; str[i]!=0; i++)
        str[i] = 0; //没有这一句有问题。。就过不了ural1297,比如数据:ababa aba
    for(i=1; i<n; i++)
    {
        if( mx > i )
            p[i] = _min( p[2*id-i], p[id]+id-i );
        else
            p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
            ;
        if( p[i] + i > mx )
        {
            mx = p[i] + i;
            id = i;
        }
    }
}

void init()
{
 int i, j, k;
 str[0] = '$';
 str[1] = '#';
 for(i=0; i<n; i++)
 {
  str[i*2+2] = s[i];
  str[i*2+3] = '#';
 }
 n = n*2+2;
 s[n] = 0;
}

int main()
{
 int i, ans;
 int ncase;
 cin>>ncase;
 while(ncase--)
 {
     cin>>s;
     n=strlen(s);
     init();
     kp();
     ans=0;
     for(i=0;i<n;i++)
     if(p[i]>ans) ans=p[i];
     cout<<ans-1<<endl;
 }
 return 0;
}
ps:顺带普及一下这四种方法:

http://blog.youkuaiyun.com/kangroger/article/details/37742639:他总结的比较详细,只是里面一些代码都少打了一个=,大家查阅的时候要注意。


另外还有一个:点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值