## LeetCode 5 Longest Palindromic Substring

``````class Solution {
public String longestPalindrome(String s) {
int len=s.length();
if(len<2){
return s;
}
int maxLen=0;
int start=0;
for(int i=0;i<len-1;i++){
int left=i,right=i;
while(left>=0 && right<=len-1 && s.charAt(left)==s.charAt(right)){
left--;
right++;
}
if(maxLen<right-left-1){
maxLen=right-left-1;
start=left+1;
}
left=i;right=i+1;
while(left>=0 && right<=len-1 && s.charAt(left)==s.charAt(right)){
left--;
right++;
}
if(maxLen<right-left-1){
maxLen=right-left-1;
start=left+1;
}
}
return s.substring(start,start+maxLen);//左闭右开
}
}``````

Manacher时间复杂度为O(n)。

1.r右端点<=R右端点&&r左端点>=R中心点**,如图示这种情况

2.右端点< R右端点&&r左端点< R中心点，如下图

3.r右端点>R右端点

``````/*
String:加'#'处理后的回文串
MaxR:最长回文半径
flag:最长回文半径对应的中心点下标
cnt[i]:以i为中心对应的回文半径
length:String长度
*/
for i to length
if MaxR > i:               //如果当前点被最长回文半径包含
cnt[i]=min(cnt[2*flag-i],MaxR-i) //取情况1和情况2中较小的（防止超出MaxR范围）
else:
cnt[i]=1
while(String[i+cnt[i]] == String[i-cnt[i]]):
cnt[i]++;
if i+cnt[i] > MaxR:
MaxR=i+cnt[i],flag=i;
``````

``````void Manacher(char s[],int len) {//原字符串和串长
int l = 0;
String[l++] = '\$'; // 0下标存储为其他字符,防止越界
String[l++] = '#';
for (int i = 0; i < len; i++) {
String[l++] = s[i];
String[l++] = '#';
}
String[l] = 0; // 空字符
int MaxR = 0;
int flag = 0;
for (int i = 0; i < l; i++) {
cnt[i] = MaxR > i ? min(cnt[2 * flag - i], MaxR - i) : 1;//2*flag-i是i点关于flag的对称点
while (String[i + cnt[i]] == String[i - cnt[i]])
cnt[i]++;
if (i + cnt[i] > MaxR) {
MaxR = i + cnt[i];
flag = i;
}
}
}
/*
* String: \$ # a # b # a # a # b # a # 0
* cnt:    1 1 2 1 4 1 2 7 2 1 4 1 2 1
*/
``````

``````class Solution {
public String longestPalindrome(String s) {
if(s==null||s.length()<=1)
return s;
String t = "#";
for (int i = 0; i < s.length(); ++i) {
t += s.charAt(i);
t += "#";
}

// Process t
int [] p=new int[t.length()];
int mx = 0, id = 0, resLen = 0, resCenter = 0;
for (int i = 0; i < t.length(); ++i) {
p[i] = mx > i ? Math.min(p[2 * id - i], mx - i) : 1;
while (i - p[i] >= 0 && i + p[i] < t.length() && t.charAt(i + p[i]) == t.charAt(i - p[i])){
p[i]++;
}
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
if (resLen < p[i]) {
resLen = p[i];
resCenter = i;
}
}
return s.substring((resCenter - (resLen-1))/ 2,(resCenter + (resLen-1))/ 2);
}
}``````

return那一句调试了很久，记录一下过程

0条评论