manacher算法(马拉车算法)—— 最长回文子串

时间复杂度:O(n)
空间复杂度:O(n)

public class longestPalindrome_5 {
    public static void main(String[] args) {
        String s = "babac";
        System.out.println(new longestPalindrome_5().longestPalindrome(s));
    }
    /*
    manachaer 算法
     */
    public String longestPalindrome(String s){
        char[] res = helper(s);
        int[] PArr = new int[res.length];//回文半径数组(以当前数的位置为中心的回文数组的半径)
        //R是当前最大回文半径的最右边界的右一个值(也就是最大回文数组的右边界向后移动一个位置,有效的回文半径区域是 R - 1)
        //C是当前R最大的时候的圆心位置
        int R = -1,C = -1;
        int maxL = Integer.MIN_VALUE;
        for(int i = 0;i != res.length;i++){
            //当R < i时,当前字符的位置不在R内,继续往外扩散,加速的位置是自身,即是1
            //当R > i时,当前字符的位置在R内,以C为对称点,找i的对称点i'
            //1.i'的回文半径在R内或者在R内;那么i的回文半径就是i'位置的回文半径, PArr[i'];
            //2.i'的回文半径和以C为对称点R的对称点R'重合,那么i的回文半径最低长度为R - i(该算法的加速的地方),需要在向R的后边继续扩散判断是否能成功
            PArr[i] = R > i ?Math.min(PArr[2 * C - i],R - i):1;
            while(i + PArr[i] < res.length && i - PArr[i] > -1 ){
                if(res[i + PArr[i]] == res[i - PArr[i]]){//往外扩散判断,该分支其实是 当R < i 和 当R > i,且i'的回文半径与R'重合的情况执行的,
                    PArr[i]++;//扩成功当前字符的回文半径数组增加
                }else{//R > i,i'的回文半径在R'之内和之外执行的,不用扩散,
                    break;
                }
            }
            //每次判断当前最右的回文半径的右边界是否是最右的,不是就更新,同时也更新对称点的位置,R 和 C是一一对应的
            if(R < i + PArr[i]){
                R = i + PArr[i];
                C = i;
            }
            //每次记录最大回文的最大长度
            maxL = Math.max(maxL,PArr[i]);//max - 1 就是最长回文子串的长度
        }
        return maxL;
    }
    /*
    处理字符串,添加特殊字符(字符可以是任意)
     */
    public char[] helper(String s){
        char[] str = s.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 ?'#':str[index++];
        }
        return res;
    }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值