问题描述:
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.
我的解题思路:
题目要求的是最长回文子串,关键字是回文 子串。之前遇到过求解最长不重复子串的问题,这两个问题还是有一定相似性的。所以一开始是想借鉴《最长不重复子串的问题》的思路,但是想了一会之后发现这两个问题有着一个本质的区别:就是本题的子问题不重复,从每个字符开始寻找回文子串都是一个独立的问题,无法应用到之前遍历的结果。因此,本题不适合直接照搬《最长不重复子串的问题》的思路。
再分析回文子串的性质,发现回文子串都是中心对称的,一个回文子串的对称中心要么是两个相等的字符,要么是一个独立的字符。如“bccb”中心是cc ‘dbd’中心是b。
于是就有这样的想法:能不能对原字符串进行遍历,寻找对称中心。每次寻找到一个对称中心之后,再从中心向两边扩展,记录该中心扩展得到的最长回文子串的长度和起始位置。这样对整个字符串遍历完之后,就可以得到所有子串中最长的回文子串。编写程序如下:
class Solution {
public:
string longestPalindrome(string s) {
int len=s.length();
int max_len=0;
int max_idx=0;
int curr_len=0;
int pt2=len-1;int pt1=len-2;
int tmp1=0;int tmp2=0;
if(len<=1)
return s;
while((pt1>=0)) //寻找对称中心是两个相等字符的回文子串
{
if(s[pt1]==s[pt2]) //找到一个对称中心
{
tmp1=pt1;
tmp2=pt2;
while(tmp1>=0&&tmp2<=len-1) //从中心向两边进行扩展
{
if(s[tmp1]==s[tmp2])
{
curr_len=tmp2-tmp1+1;
tmp1--;
tmp2++;
}
else
break;
}
if(curr_len>max_len) //记录当前最长的回文子串的长度和下标
{
max_len=curr_len;
max_idx=tmp1+1;
}
pt1--;
pt2--;
}
else
{
pt1--;
pt2--;
}
}
pt2=len-1; pt1=len-3;
tmp1=0; tmp2=0;
while((pt1>=0)) //寻找对称中心为单个字符的回文子串
{
if(s[pt1]==s[pt2])
{
tmp1=pt1;
tmp2=pt2;
while(tmp1>=0&&tmp2<=len-1)
{
if(s[tmp1]==s[tmp2])
{
curr_len=tmp2-tmp1+1;
tmp1--;
tmp2++;
}
else
break;
}
if(curr_len>max_len)
{
max_len=curr_len;
max_idx=tmp1+1;
}
pt1--;
pt2--;
}
else
{
pt1--;
pt2--;
}
}
string res(s,max_idx,max_len);
return res;
}
};
编写完程序之后,提交,本来还担心时间复杂度不符合要求,没想到一次就accept了。分析下我的程序,最坏的复杂度应该是2*O(n^2)=O(n^2),最好的情况应该能达到O(n)。