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算法实际上就是对枚举对称中心这一做法的优化,找到对称中心,对称中心左右两侧互为逆序,所以左右已经枚举过的字符结果可以直接拿来右侧使用