Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd" Output: "bb"
Manache算法直接过,但是Python的耗时1400ms,一直没有优化过去。。。。。,表达式求值在Python中尽量用变量替换,可以减少耗时
C
char* longestPalindrome(char* s) {
const int len = 2*strlen(s) + 5;
char *str = (char *)malloc(len);
int *p = (int *)malloc(len*sizeof(int));
*str = '#';
*p = 1;
int slen = 1;
while(*s)
{
str[slen++] = *s++;
str[slen++] = '#';
}
str[slen] = '\0';
int pos = 0;
int maxpos = 0;
int maxright = 0;
int maxlen = 0;
for(int i=1;i<slen;i++)
{
p[i] = 1;
if(i<maxright)
p[i] = p[2*pos-i]<maxright-i?p[2*pos-i]:maxright-i;
while(i+p[i]<slen&&i-p[i]>=0&&str[i+p[i]]==str[i-p[i]])
p[i]++;
if(maxright<i+p[i]-1)
{
pos = i;
maxright=pos+p[pos]-1;
}
if(maxlen<p[i])
{
maxlen = p[i];
maxpos = i;
}
}
char *rs = (char *)malloc(maxlen*sizeof(char));
char *r = rs;
for(int i=maxpos-p[maxpos]+1;i<maxpos+p[maxpos];i++)
if(str[i]!='#')*r++ = str[i];
*r = '\0';
return rs;
}
C++
class Solution {
public:
string longestPalindrome(string s) {
const int len = s.size();
char *str = (char *)malloc(2*len + 5);
*str = '#';
int slen = 1;
for(int i=0;i<len;i++)
{
str[slen++] = s[i];
str[slen++] = '#';
}
str[slen] = '\0';
int *p = (int *)malloc(slen*sizeof(int));
*p = 1;
int pos = 0;
int maxpos = 0;
int maxright = 0;
int maxlen = 0;
for(int i=1; i<slen; i++)
{
p[i] = 1;
if(i<maxright)
p[i] = p[2*pos-i]<maxright-i?p[2*pos-i]:maxright-i;
while(i+p[i]<slen&&i-p[i]>=0&&str[i+p[i]]==str[i-p[i]])
p[i]++;
if(maxright<i+p[i]-1)
{
pos = i;
maxright=pos+p[pos]-1;
}
if(maxlen<p[i])
{
maxlen = p[i];
maxpos = i;
}
}
char *rs = (char *)malloc(maxlen*sizeof(char));
char *r = rs;
for(int i=maxpos-p[maxpos]+1;i<maxpos+p[maxpos];i++)
if(str[i]!='#')*r++ = str[i];
*r = '\0';
return rs;
}
};
Java
class Solution {
public String longestPalindrome(String s) {
int len = 2*s.length() + 5;
char[] str = new char[len];
int[] p = new int[len];
p[0] = 1;
len = 0;
str[len++] = '#';
for(int i=0;i<s.length();i++){
str[len++] = s.charAt(i);
str[len++] = '#';
}
str[len] = '\0';
int pos = 0;
int maxpos = 0;
int maxright = 0;
int maxlen = 0;
for(int i=1;i<len;i++){
p[i] = 1;
if(i<maxright)
p[i] = p[2*pos-i]<maxright-i?p[2*pos-i]:maxright-i;
while(i+p[i]<len&&i-p[i]>=0&&str[i+p[i]]==str[i-p[i]])
p[i]++;
if(maxright<i+p[i]-1){
pos = i;
maxright=pos+p[pos]-1;
}
if(maxlen<p[i]){
maxlen = p[i];
maxpos = i;
}
}
StringBuffer rs = new StringBuffer();
for(int i=maxpos-p[maxpos]+1;i<maxpos+p[maxpos];i++)
if(str[i]!='#'){
rs.append(str[i]);
}
return rs.toString();
}
}
Python
class Solution:
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
str = '#'+'#'.join(s)+'#'
pos,maxpos,maxlen,maxright = 0,0,0,0
slen = len(str)
p = [1]
for i in range(1,slen):
plen = 1;
if i<maxright:
plen = min(p[2*pos-i],maxright-i)
a = i+plen
b = i-plen
while a<slen and b>=0 and str[a]==str[b]:
a+=1
b-=1
plen = a-i;
if maxright<plen:
pos,maxright = i,plen
if maxlen<plen:
maxpos,maxlen = i,plen
p.append(plen)
return "".join(filter(lambda x:x!='#',str[maxpos-maxlen+1:maxpos+maxlen]))