马拉车(Manachar)——最长回文串

简介

Manachar 算法在 O(n) 时间处理出以字符串中每一个字符为中心的回文串半径。Manacher 算法通过将原字符串每个字符的左右两边都插入一个分隔符的方式,将长度为奇数的回文串和长度为偶数的回文串一起考虑。(分隔符不在原串中出现,一般情况下可以用 # 号代表)

预处理

实现

马拉车的主要思想就是利用回文串两边相同的性质,用已知回文串去推未知回文串。

代码

public class Main
{
    public static int solution(String s)
    {
        int sc = -1, sr = -1, ansCenter = 0, ansLen = 0;
        int[] p = new int[2 * s.length() + 1];
        StringBuilder str = new StringBuilder();
        str.append('#');
        for (char ch : s.toCharArray())
            str.append(ch + "#");
        for (int i = 0; i < str.length(); i++)
        {
            p[i] = sr > i ? Math.min(p[2 * sc - i], sr - i) : 1;
            while (i + p[i] < str.length() && i - p[i] > -1 && str.charAt(i + p[i]) == str.charAt(i - p[i]))
                ++p[i];
            if (sr < i + p[i])
            {
                sr = i + p[i];
                sc = i;
            }
            if (ansLen < p[i])
            {
                ansLen = p[i];
                ansCenter = i;
            }
        }
        int start = (ansCenter - ansLen + 1) / 2;
        System.out.println(s.substring(start, start + ansLen - 1));
        return ansLen - 1;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        System.out.println(solution(s));
    }
}

参考Grandyang

posted @ 2019-08-27 11:13  Vivid-BinGo  阅读(419)  评论(0编辑  收藏  举报