Manacher算法 -- 回文长度算法(java)

265 篇文章 2 订阅
235 篇文章 0 订阅

Manacher算法

什么是Manacher算法:
Manacher算法是一种用于寻找最长回文子串的算法,时间复杂度为O(n),其中n是字符串的长度。该算法是由Gusella和Shannon于1980年提出的,它利用了回文串的特殊性质,以实现高效的查找。

算法步骤如下:
1. 初始化一个数组p,p[i]表示以字符i为中心的最长回文子串的半径长度(即回文串的长度除以2)。
2.初始化一个变量max_len,用于记录已经找到的最长回文子串的长度,初始值为0。
3. 从左到右遍历字符串,对于每个字符i,进行以下操作:
a. 如果i的左侧和右侧都有回文子串,则更新max_len为左侧回文子串长度和右侧回文子串长度的较大值,并更新p[i]为max_len的一半。
b. 如果i的左侧没有回文子串,则将p[i]设为0。
c. 如果i的右侧没有回文子串,则将p[i]设为max_len的一半。
4. 在遍历过程中不断更新max_len和p数组,最终得到的max_len即为最长回文子串的长度。
通过遍历p数组,可以得到最长回文子串的中心字符和长度。

Manacher算法的关键在于如何利用已经找到的回文子串信息来快速判断新的字符是否能够扩展已有的回文子串。通过维护p数组,可以在O(1)的时间内得到新字符能够扩展的最长回文子串长度,从而实现高效的查找。
该算法的实现比较简单,时间复杂度较低,因此在处理长回文子串的问题时具有很好的应用价值。

代码演示

  /**
     * 最长回文串的长度处理
     * @param s
     * @return
     */
    public static int manacher(String s) {
        if (s == null || s.length() == 0){
            return 0;
        }
        // abc  ->  #a#b#c#
        char[] chars = manacherString(s);
        //回文半径数组
        int[] pArr = new int[chars.length];
        //回文最右边界
        int R = -1;
        //回文中心
        int C = -1;
        //保存最大值
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < chars.length;i++){
            //i 在R 的半径内。
            pArr[i] = R > i ? Math.min(pArr[2 * C - i],R - i) : 1;

            while (i + pArr[i] < chars.length && i - pArr[i] > -1){
                if (chars[i + pArr[i]] == chars[i - pArr[i]]){
                    pArr[i]++;
                }else {
                    break;
                }
            }
            if (i + pArr[i] < chars.length){
                R = i + pArr[i];
                C = i;
            }
            max = Math.max(max,pArr[i]);
        }
        return max - 1;
    }

        /**
         * 处理字符串  abc  ->  #a#b#c#
         * @param str
         * @return
         */
    public static char[] manacherString(String str){
        char[] chars = str.toCharArray();
        char[] ans = new char[chars.length * 2 + 1];
        int index = 0;
        for (int i = 0 ; i < ans.length;i++){
            ans[i] = (i & 1) == 0 ? '#' : chars[index++];
        }
        return ans;
    }

上期经典 KMP 算法

KMP–高效字符串匹配算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值