最长回文(manacher算法)(fromHDU)

给出一个只由小写英文字符a,b,c…y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c…y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa

abab
Sample Output
4
3
今天学习了一个新算法:manacher算法。
是一个针对于回文字符串算法。消化了以后觉得这个算法是有动态规划的味道的,因为借助前面状态,可以更快效率的求出当前的状态时的串长度度。
就这道题,如果直接去做,百分之九十的概率是要超时的,所以必须换一个思路,那就是manacher算法。
现在要我我说这个算法,发现这个好难描述,推荐一个博文:http://blog.csdn.net/xingyeyongheng/article/details/9310555
对这个算法的解释是非常详细的。
代码:

import java.util.Scanner;

public class Main 
{

    public static void main(String[] args) 
    {
         Scanner sc=new Scanner(System.in);
         while(sc.hasNext())
         {
             String s=sc.next();
             char c[]=new char[s.length()*2+3];
             c[0]='*';

             for(int i=0;i2+1]='#';
                 c[i*2+2]=s.charAt(i);
             }
             c[c.length-2]='#';
             c[c.length-1]='?';//这些都是前期处理,在每个字符之前和两个端点插入一个'#'('#'只是一个在题目要求没有出现过的字符),并且在此之上还要在这个字符串两端加一个没出现的字符,其目的是防止数组索引越界,实际上也可以不用,而只要加一个越界判断条件就可以,但是加了这两个字符,代码会跟整洁一些
              int maxLen=0,id=0;
              int p[]=new int[c.length];//p[]是一个存储以i为中心的回文字符串长度的半径,加上自己本身,            for(int i=2;i
              {
                  if(p[id]+id>=i)
                      p[i]=Math.min(p[id-(i-id)], p[id]-(i-id));
                  else
                      p[i]=1;
                  while(c[i-p[i]]==c[i+p[i]])
                      p[i]++;
                  if(p[id]+idif(maxLen//这段就是核心代码
              System.out.println(maxLen-1);
         }
    }

}

你可能感兴趣的:(动态规划,回文字符串)