您的位置:首页 > 其它

005Longest Palindromic Substring

2015-08-29 18:38 253 查看

Longest Palindromic Substring

题目

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

答案

解法一

使用暴力的手法,以每一个字母为中心或者,以每一个字母和它的下一个字母为中心,向两边扩展,复杂度应该为O(n^2).


char* longestPalindrome(char* s) {
int i,j;
int len=0,index=0;
int tmp_len=0;
for (i = 0; s[i]!='\0'; i++)
{
tmp_len = 0;
if(s[i+1]!='\0'&&s[i]==s[i+1])
{
for (j = 0; ((i-j)>=0)&&s[i+1+j]!='\0'; j++)
{
if(s[i+1+j]==s[i-j])
{
tmp_len+=2;
if(tmp_len>len)
{
len = tmp_len;
index = i;
}
}
else break;
}
}
tmp_len = 0;
for (j = 0; ((i-j)>=0)&&s[i+j]!='\0'; j++)
{
if(s[i+j]==s[i-j])
{
if(i+j==i-j)
tmp_len++;
else tmp_len+=2;
if(tmp_len>len)
{
len = tmp_len;
index = i;
}
}
else break;

}
}
if(len%2==0)
{
if(s[index+1+len/2]!='\0')
s[index+1+len/2]='\0';
return s+(index-len/2+1);
}
else{
if(s[index+(len+1)/2]!='\0')
s[index+(len+1)/2]='\0';
return s+(index-(len+1)/2+1);
}
}


解法二

我太笨拙,网上有种O(n)方法解决问题的,开了好久,给个链接:http://www.cnblogs.com/daoluanxiaozi/p/longest-palindromic-substring.html。
核心:当发现「回文串 1 中存在回文串 2,回文串 3,回文串 4,...回文串 N」的情况,要作检测,具体是看回文串 2 和回文串 N ,回文串 3 和回文串 N-1 是否对称且相等。
在处理的时候,将每个字符间和字符串首位增加无用字符#,这样就可以避免奇偶情况了。


python代码:

str = "abcdcba "
str = "#" + "#".join(str) + "#"
print str

i = 0
mx = 0
id = 0
p = [0 ] * len(str)
while i<len(str):
if mx > i:
p[i] = min(p[ 2*id-i],mx-i)
else:
p[i] = 1

while i-p[i] >=0 and i+p[i] < len(str) and str[i-p[i]]==str[i+p[i]]:
p[i] += 1

if mx < p[i]+i:
mx = p[i] + i
id = i
i+=1

print p


c代码:

char * init(char * s){
char p[4400];
p[0]='#';
int i;
for (i = 0; s[i]!='\0' ; i++)
{
p[i*2+1] = s[i];
p[i*2+2] = '#';
}
p[i*2+1] = '\0';
return p;
}

char* longestPalindrome(char* s) {
char *ss = init(s);
int i,j;
int index = 0;
int end = 0;
int len[4400]={0};
for (i = 0;ss[i]!='\0'; i++)
{
if(end > i)
len[i] = (len[2*index - i])>(end-i)?(end-i):(len[2*index - i]);
else len[i] = 1;
while(i-len[i]>=0&&ss[i+len[i]]!='\0'&&ss[i-len[i]]==ss[i+len[i]])
len[i]++;
if(end<i+len[i])
{
end = i+len[i];
index = i;
}
}
int maxx=0;
int center_index=0;
for (i = 0;ss[i]!='\0' ; i++)
{
if(len[i]>maxx)
{
maxx = len[i];
center_index = i;
}
}
char ans[2200];
j=0;
for (i = center_index-maxx+1; i < center_index+maxx; i++)
{
if(ss[i]!='#')
ans[j++] = ss[i];
}
ans[j] = '\0';
return ans;
}


其他思路

使用dp O(n^2)

一个常见的错误

有人很快会想到这样一个方法。这个方法有缺陷,不过很容易修正。翻转S成为S’。查找S和S’最长公共子串,就是S的最长回文子串。看起来有道理的样子。用实例检验下。例如S=”caba”,S’=”abac”。S和S’的最长公共子串是”aba”,确实是S的最长回文子串。再看个例子。S=”abacdfgdcaba”,S’=”abacdgfdcaba”。S和S’的最长公共子串是”abacd”,不过很明显这不是回文。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: