String——回文字符串manacher算法

本文介绍了一种高效算法——Manacher算法,用于查找给定字符串中的最长回文子串。通过在每个字符间插入特殊符号,使得算法能统一处理奇数和偶数长度的回文子串。

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

资料来源网络 参见http://www.cnblogs.com/biyeymyhjob/archive/2012/10/04/2711527.html

找字符串中的最大回文子串


算法基本要点:

首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。然后就可以运用manacher算法。

public class Solution {
     public String longestPalindrome(String str)
    {
    	if(str == null||str.length()<2)
    		return str;
    	//对str进行预处理操作,添加‘#’;
    	StringBuilder sb=new StringBuilder("#");
    	for(int i=0;i<str.length();i++)
    	{
    		sb.append(str.charAt(i));
    		sb.append('#');
    	}
    	   str=sb.toString();
    	 return  manacher(str);
    }
	
        public String manacher(String str)
        {
        	int []p=new int[str.length()];
       //id代表当前最大回文子串中心的下标,mx表示当前最大回文子串所能达到最右端的距离+1(并没有达到!);
        	int mx=0;
        	int id=0;
        	for(int i=1;i<str.length();i++)
        	{
        		if(mx>i)
        		{
        			p[i]=p[2*id-i]<mx-i?p[2*id-i]:mx-i;
        		}
        		else
        		{
        			p[i]=1;
        		}
                //防止下标越界;更新p[i];
        		while(i-p[i]>=0&&i+p[i]<str.length()&&(str.charAt(i-p[i]) == str.charAt(i+p[i])))
        			p[i]++;
        		
        		if(i+p[i]>mx)
        		{
        			mx=i+p[i];//mx不会越界;
        			id=i;       			
        		}
        	}
        	//找出p[i]中最大的;
            int max=0;
            int index=0;
            for(int j=0;j<p.length;j++)
            {
                if(p[j]>max)
                {
                	index=j;
                	max=p[j];
                }
            }
            //如#a#b#b#a#,
   //对应的p[i]为021252121,start和end为该回文子串起始和终止的地方,
     //index == 4,max == 5,可简单的观测出start和end与max和index对应关系;
            max=max-1;
            int start=index-max;
            int end=index+max;
            
            StringBuilder sb=new StringBuilder();
            for(int k=start;k<=end;k++)
            {
            	if(str.charAt(k)!='#')
            		sb.append(str.charAt(k));
            }
            
            String string =sb.toString();
            //System.out.println(string);
            return string;
        	
       }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值