原题: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.
解答:
C++版本
string longestPalindrome(string s) {
if (s.empty()) return "";
if (s.size() == 1) return s;
int min_start = 0, max_len = 1;
for (int i = 0; i < s.size();) {
if (s.size() - i <= max_len / 2) break;
int j = i, k = i;
while (k < s.size()-1 && s[k+1] == s[k]) ++k; // Skip duplicate characters.
i = k+1;
while (k < s.size()-1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } // Expand.
int new_len = k - j + 1;
if (new_len > max_len) { min_start = j; max_len = new_len; }
}
return s.substr(min_start, max_len);
}
思路:
对于每个中心字母,存在两种情况
1:回文串长度为奇数, 例如:sddds, sbdbs
2:回文串长度为偶数, 例如:sdds, sbddddbs
上述两种情况,对称中心的字母多是重复了几次,我们可以跳过这种重复,从不重复的地方开始比较,比如对于sdds,s[i] = d时,跳过重复,s[j] = d,比较s[k + 1] == s[j - 1],直到不相等。
遍历每个字母,找到以该字母为中心字母的回文长度,更新较大者。
注意:
1、i = k+1,很有优势,因为重复的字母没必要再遍历第一次,比如fasdddsac的中间串,当中心字母为d(第一个d)时,以及可以确定回文是asdddsa,就没必要再遍历第二、第三个d,因为重复了,中心元素都是d,得到的回文串长度时一样的,所有没比较比较。
2、 if (s.size() - i <= max_len / 2) break,提前跳出循环,因为后面再计较,长度也不可能超过目前的最大长度。