leetcode5. 最长回文子串(Manacher - java)

Manacher回文算法

  • leetcode5. 最长回文子串
    • Manacher 算法
  • manacher 算法

leetcode5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:
输入:s = “cbbd”
输出:“bb”

提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成

Manacher 算法

介绍下Manacher算法:
Manacher 算法是一种用于寻找最长回文子串的算法。它的时间复杂度为 O(n),其中 n 是字符串的长度。以下是 Manacher 算法的基本步骤:

  1. 初始化一个字符串,其中包含一个长度为 n+1 的回文串,以使得字符串的中间字符为字符串的中间字符,例如:P=“banana”。
  2. 找到字符串 P 的中心字符,将其标记为 center。
  3. 从字符串的两端开始遍历 P,对于每个字符,如果其与 center 的距离大于字符串的长度的一半,则将该字符移动到与 center 对齐的位置,即将其插入到 P 中相应位置。
  4. 在 P 中找到最长的回文子串的右边界 max_right,左边界为 center。
  5. 对于每个字符,如果其与 center 的距离小于等于 max_right 与 center 的距离减去 1,则将该字符的回文半径(即该字符与 center 的距离减去 max_right 与 center 的距离)加入到一个栈中。
  6. 遍历栈中的回文半径,对于每个半径 r,如果其左侧有一个半径为 r-1 的回文子串,则可以扩展该回文子串,直到其与 center 的距离为 r。
  7. 最终得到的字符串就是原字符串的最长回文子串。

Manacher 算法的关键在于利用回文串的特性,将字符串中的字符移动到合适的位置,以便于后续的回文子串的扩展。

manacher 算法只用于计算回文字符串,都是固定代码,
因此直接看代码吧.

leetcode5. 最长回文子串(Manacher - java)_第1张图片

代码演示

class Solution {
    public String longestPalindrome(String s) {
        return manacher(s);
    }

     public static String manacher(String s){
        if (s == null || s.length() == 0){
            return null;
        }
        char[] str = manacherString(s);
        int R = -1;
        int C = -1;
        int[] pArr = new int[str.length];
        int max = Integer.MIN_VALUE;
        int pos = 0;
        for (int i = 0; i < str.length;i++){
            pArr[i] = R > i ? Math.min(pArr[2 * C - i],R - i) : 1;
            while(i + pArr[i] < str.length && i - pArr[i] > -1){
                if (str[i + pArr[i]] == str[i - pArr[i]] ){
                    pArr[i]++;
                }else {
                    break;
                }
            }
            if (i + pArr[i] > R){
                R = i + pArr[i];
                C = i;
            }
            if (max < pArr[i]){
                pos = i;
                max = pArr[i];
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
          for (int i = pos - max + 1; i < pos + max; i++){
            if (str[i] != '#'){
                stringBuilder.append(str[i]);
            }
        }
        return stringBuilder.toString();
    }

    public static char[] manacherString(String s){
        char[] chars = s.toCharArray();
        int index = 0;
        char[] manacher = new char[chars.length * 2 + 1];
        for (int i = 0; i < manacher.length;i++){
            manacher[i] = (i & 1) == 0 ? '#' : chars[index++];
        }
        return manacher;
    }
}

manacher 算法

Manacher算法 – 回文长度算法

你可能感兴趣的:(算法,数据结构,java,java,python,开发语言,数据结构,算法,leetcode)