最长回文(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.youkuaiyun.com/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;i<s.length();i++)
	    	 {
	    		 c[i*2+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<c.length-1;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]+id<p[i]+i)
	    			  id=i;
	    		  if(maxLen<p[i])
	    			  maxLen=p[i];
	    	  }//这段就是核心代码
	    	  System.out.println(maxLen-1);
	     }
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值