最长回文子串-Manacher算法

来源:互联网 发布:克里斯埃文斯知乎 编辑:程序博客网 时间:2024/05/16 11:06

代码来源:程序员代码面试指南


主要是Manacher算法的使用,具体请参考程序员代码面试指南P483,有很详细的介绍。


题目,来自牛客网:


对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。

给定字符串A以及它的长度n,请返回最长回文子串的长度。

测试样例:

"abc1234321ab",12
返回:7

代码如下,使用Manacher算法时间复杂度可达到O(N)!
import java.util.*;public class Palindrome {    //加入特殊字符'#',得到新的字符串    public char[] manacherString(String str){        char[] charArr=str.toCharArray();        char[] res=new char[str.length()*2+1];        int index=0;        for(int i=0;i<res.length;i++){            res[i]=(i&1)==0?'#':charArr[index++];        }        return res;    }    public int getLongestPalindrome(String A, int n) {        // write code here        if(A==null||n<=0)            return 0;        char[] charArr=manacherString(A);  //manacher字符串        int[] pArr=new int[charArr.length]; //以charArr[i]为中心的回文子串半径数组        int index=-1;//中心位置        int pR=-1;//当前回文子串最右将达到的位置        int max=Integer.MIN_VALUE;//最小值        for(int i=0;i<charArr.length;i++){//manacher算法核心部分            pArr[i]=pR>i?Math.min(pArr[2*index-i],pR-i):1;            while(i+pArr[i]<charArr.length&&i-pArr[i]>=0){//半径在合理的范围之内                if(charArr[i+pArr[i]]==charArr[i-pArr[i]])                    pArr[i]++;                else{                    break;                }            }            if(i+pArr[i]>pR){//超过了之前pR的值                 pR=i+pArr[i];//更新pR                 index=i;     //更新index            }            max=Math.max(max,pArr[i]);//得到半径的最大值           }        return max-1;//半径减1就是之前没有加特殊字符'#'的最长回文子串的长度    }}


1 0