leetcode 214. 最短回文串 Manachar解法

105 阅读1分钟

来源:leetcode.cn/problems/sh…

214 最短回文串 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。

示例 1:

输入:s = "aacecaaa"
输出:"aaacecaaa"

示例 2:

输入:s = "abcd"
输出:"dcbabcd"

提示:

0 <= s.length <= 5 * 104
s 仅由小写英文字母组成

题解:

public String shortestPalindrome(String s) {
    if (s.length() == 1) return s;
    char[] chars = new char[(s.length() << 1) + 1];
    for (int i = 0; i < chars.length; i++) {
        chars[i] = i % 2 == 0 ? '#' : s.charAt(i / 2);
    }
    int[] dp = new int[chars.length];
    int c = chars.length + 1, l = chars.length + 1, start = chars.length + 1;
    for (int i = chars.length - 1; i >= 0; i--) {
        int radius = i >= l ? Math.min(dp[c - i + c], i - l) : 1;
        while (i - radius >= 0 && i + radius < chars.length && chars[i - radius] == chars[i + radius]) radius ++;
        dp[i] = radius;
        l = i - radius + 1;
        c = i;
        if (l == 0) {
            start = i - l;
            break;
        }
    }
    StringBuffer sb = new StringBuffer();
    for (int j = s.length() - 1; j >= start; j--) {
        sb.append(s.charAt(j));
    }
    return sb + s;
}

在寻找最短回文串时需要对每一个字符进行枚举,Manacher算法实际上就是对枚举对称中心这一做法的优化,找到对称中心,对称中心左右两侧互为逆序,所以左右已经枚举过的字符结果可以直接拿来右侧使用