最长回文子串。就是给定一个字符串S,找出其中的最长回文子串,并返回该子串。
string longestPalindrome(string s)
{
int n = s.length();
if (n == 0) return "";
string longest = s.substr(0, 1); // a single char itself is a palindrome.从0位置开始长度为1的字符串
for (int i = 0; i < n-1; i++) {
string p1 = expandAroundCenter(s, i, i); // assume the palindrome num is odd(寻找以i为中点的奇数回文)
if (p1.length() > longest.length())
longest = p1;
string p2 = expandAroundCenter(s, i, i+1); // assume the palindrome num is even(寻找以i,i+1为中心的偶数回文)
if (p2.length() > longest.length())
longest = p2;
}
return longest;
}
// 从c1, c2开始 向两侧展开,找到最长的palindrome
// e.g. 如果已经知道 "aba"是字符串"cabac"的一个字串,palindrome,
// 则向两侧展开时,"c" == "c", 即 s[l] == s[r],所以能够继续得到更长的palindrome
string expandAroundCenter(string s, int c1, int c2)
{
int l = c1, r = c2;
int n = s.length();
while (l >= 0 && r <= n-1 && s[l] == s[r]) { // 从c1/l, c2/r开始,向当前位置两侧移动指针
l--;
r++;
}
return s.substr(l+1, r-l-1);
}
这种解法中,外层循环遍历的是子字符串的中心点,内层循环则是从中心扩散,一旦不是回文就不再计算其他以此为中心的较大的字符串。由于中心对称有两种情况,一是奇数个字母以某个字母对称,而是偶数个字母以两个字母中间为对称,所以我们要分别计算这两种对称情况。