题目描述:
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.
算法一:
最开始看到题目时,还是首先使用暴力法求解试水。首先,编写函数判断某个字符串是否是回文字符串。该函数做法为:将原字符串分割为长度相等的字符串s1和s2(若字符串长度为奇数,则忽略中间位置的字符,中间字符不影响字符串的回文性),接着,判断s1的第一位与s2的最后一位是否相同,s1的第二位与s2的倒数第二位是否相同,以此类推,直至s1的最后一位与s2的第一位。若其中有一位不同,则函数返回结果0,表示字符串不是回文字符串。否则,函数返回字符串的长度。
接着,对于一个给定的字符串,遍历该字符串的所有子字符串,用上述函数判断其是否为回文字符串,并实时更新当前最大长度的回文字符串。最终返回结果。
int PalindromeLen(string s)
{
int len=s.length();
bool is=true;
if (len%2==0)
{
string str1=s.substr(0,len/2);
string str2=s.substr(len/2,len/2);
int i,j;
for (i=0,j=str2.length()-1;i<str1.length();i++,j--)
{
if (str1[i]!=str2[j])
is=false;
}
if (is)
return s.length();
else
return 0;
}
else
{
string str1=s.substr(0,len/2);
string str2=s.substr(len/2+1,len/2);
int i,j;
for (i=0,j=str2.length()-1;i<str1.length();i++,j--)
{
if (str1[i]!=str2[j])
is=false;
}
if (is)
return s.length();
else
return 0;
}
}
string longestPalindrome(string s) {
if (s.length()==1)
return s;
int maxLen=0;
int l;
string maxStr="";
string str;
for (int i=0;i<s.length();i++)
{
for (int j=i+1;j<s.length();j++)
{
str=s.substr(i,j-i+1);
if (PalindromeLen(str)>maxLen)
{
maxLen=PalindromeLen(str);
maxStr=str;
}
}
}
return maxStr;
}
提交后,果不其然,这种算法是超时的。遍历全部子字符串的复杂度为O(n^2),判断是否为回文字符串的复杂度为O(n),代码的时间复杂度为O(n^3)。很明显,需要另一种复杂度更低的算法。
算法二:
首先,为避免出现越界,当字符串长度为0时,返回空字符串,当字符串长度为1时,返回字符串本身。
假设要判断的字符串s为gabcdcbak。则算法步骤为:在字符串中的某一位i,判断s[i]与s[i+1]是否相等,若不相等,则i++,继续遍历字符串。如果相等,则用变量b记录子字符串开头,初始为b=i,用变量e记录子字符串结尾,初始为e=i+1。接着,判断s[b]与s[e]是否相等,若相等,则b--,e++,扩展子字符串,并继续判断s[b]与s[e]是否相等。当子字符串已经越界或者s[b]与s[e]不相等时,记录从位置b+1到位置e-1的回文子字符串,并更新当前最大长度的回文子字符串。该算法的复杂度为O(n^2)。
string longestPalindrome(string s)
{
if (s.length()==0)
return "";
else if (s.length()==1)
return s;
else if (s.length()==2)
{
if (s[0]==s[1])
return s;
else
return "";
}
string result;
int b,e;
for (int i=0;i<s.length();i++)
{
if (i>0&&s[i-1]==s[i+1])
{
b=i-1;
e=i+1;
while (b>=0&&e<s.length()&&s[b]==s[e])
{
b--;
e++;
}
b++;
e--;
if (result.length()<e-b+1)
result=s.substr(b,e-b+1);
}
if (s[i]==s[i+1])
{
b=i;
e=i+1;
while (b>=0&&e<s.length()&&s[b]==s[e])
{
b--;
e++;
}
b++;
e--;
if (result.length()<e-b+1)
result=s.substr(b,e-b+1);
}
}
return result;
}