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(n2)
很不幸的是, 这种方法 TLE 了。
于是, 我们采用了另一种方法, 指针cur从头向后移动, 如果s[cur] == s[cur + 1] || s[cur] == s[cur + 2], 说明形成回文字串了, 记录当前的cur值, 并试图扩展回文串, 获取最大回文字串
My Code AC
class Solution {
public:
void getPalindromic(const string & s, int pcur_begin, int pcur_end, int & g_begin, int & g_end, int & len)
{
while (pcur_begin != 0 && pcur_end != s.size() - 1 && s[--pcur_begin] == s[++pcur_end]);
// s[pcur_begin] != s[pcur_end] 此时, pcur_begin 落在其实字符的前一个字符, pcur_end 在结束字符的后一个字符
if (s[pcur_begin] != s[pcur_end] && len < pcur_end - pcur_begin - 1)
{
len = pcur_end - pcur_begin - 1;
g_begin = pcur_begin + 1;
g_end = pcur_end - 1;
}
if (s[pcur_begin] == s[pcur_end] && len < pcur_end - pcur_begin + 1)
{
len = pcur_end - pcur_begin + 1;
g_begin = pcur_begin;
g_end = pcur_end;
}
}
string longestPalindrome(string s) {
if (s.size() <= 1)
return s;
int len = 0;
int g_begin = 0;
int g_end = 0;
for (int cur = 0; cur != s.size(); cur++)
{
if (s[cur] == s[cur + 1])
{
int pcur_begin = cur;
int pcur_end = cur + 1;
getPalindromic(s, pcur_begin, pcur_end, g_begin, g_end, len);
}
if (s[cur] == s[cur + 2])
{
int pcur_begin = cur;
int pcur_end = cur + 2;
getPalindromic(s, pcur_begin, pcur_end, g_begin, g_end, len);
}
}
return string(s.begin() + g_begin, s.begin() + g_end + 1);
}
};
大神们的代码
demo1
大神的思路与我们的总体一致, 不过, 在对重复字符的操作上, 大神明显简练, 并且我们的代码中由于
s[−−pcur_begin]==s[++pcur_end]
的存在, 无形中降低了代码的可读性, 并且在失败的时候, 又一次执行了++操作, 和我们的预期不太一致, 这种写法需要避免
另外 substr方法, 值得借鉴
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);
}