5. 最长回文子串
没什么特别的,就是马拉车算法。
关于马拉车算法,dp[i]是半径,除i这点的半径,于是最后会得到的结果是:
int start = (index-MAX)/2;
s.substring(start,start+MAX);
原因是最后最长的半径比如从#开始,于是最后长度就是dp[index],而起点必然减半
public String longestPalindrome(String s) {
return manacher(s);
}
//返回^开头 $结尾
public String preSolve(String s) {
StringBuilder builder = new StringBuilder();
builder.append('^');
for (int i = 0; i < s.length(); i++) {
builder.append("#").append(s.charAt(i));
}
builder.append('#');
builder.append('$');
return builder.toString();
}
public String manacher(String s) {
String t = preSolve(s);
int[] dp = new int[t.length()];
int border = 1, mid = 1;
int index = -1, MAX = -1;
for (int i = 1; i < t.length() - 1; i++) {
int minn = 0;
if (i < border) {
int j = 2 * mid - i;
minn = Math.min(border - i, dp[j]);
}
while (t.charAt(i + minn) == t.charAt(i - minn)) minn++;
dp[i] = minn - 1;
if (i + dp[i] > border) {
border = i + dp[i];
mid = i;
}
if (dp[i] > MAX) {
MAX = dp[i];
index = i;
}
}
int start = (index-MAX)/2;
return s.substring(start,start+MAX);
}