这道题花了好长时间
题目描述
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:
Input: “cbbd”
Output: “bb”
算法分析
- 为了测试系统,先写一个O(n3)的算法,对于任意的起点i和终点j,判断s[i,j]是否为回文串。GG
- 为了提升算法,优化到O(n2).对于任意的中心位置i,向两端扩展k,判断s[i-k]==s[i+k]。
- 后来发现了一个复杂度为O(n)的Manacher’s Algorithm
具体算法内容讲解如果看的人多就更(^ ^)估计是没机会了
class Solution {
public:
string longestPalindrome(string s) {
if(s.length()==0)
return "";
string tmp = "#";
int length = s.length();
for (int i = 0;i < length;++i)
{
tmp += s[i];
tmp += '#';
}
int len = 2 * length + 1;
int *p = new int[len];
for (int i = 0;i < len;++i)
p[i] = 0;
int start, end;
updateP(tmp,p, len,&start,&end);
int ss = start / 2;
length = (end - start+1)/2 ;
return s.substr(ss, length);
}
void updateP(string s,int *p, int len,int *start,int *end)
{
int mx=0, po=0, ans = 0;
for (int i = 1;i < len-1;++i)
{
p[i]=mx>i?Min(mx-i,p[2*po-i]):1;
while (s[i - p[i]] - s[i + p[i]] == 0) {
p[i]++;
if (i - p[i] < 0 || i + p[i] >= len)
break;
}
if (p[i] + i > mx) {
mx = p[i] + i;
po = i;
}
if (ans < p[i]) {
ans = p[i];
*start = i - p[i]+1;
*end = i + p[i]-1;
}
}
}
int Min(int a, int b)
{
return a < b ? a : b;
}
};
- 由上一篇学到的绝学,这一次学以致用,在算法3的基础上加快了cin
static int fastiofunc() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}
static int fastio = fastiofunc();
- 瞄了一眼最好的算法,居然是用了trick的O(n2)算法,撞出来的最好结果,社会社会
class Solution {
public:
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);
}
};
要说为什么的话,因为这两行
while (k < s.size()-1 && s[k+1] == s[k]) ++k; // Skip duplicate characters.
i = k+1;
onjudge在构造让O(n2)达到最坏复杂度的情况,基于这个算法考虑,最坏情况大多数是很长的重复相同字符的字符串,比如“aaaaaaaaaaaaaa”,这样只要处理这种情况,加入上面这两句,就能有效避免O(n2)最坏情况出现。不得不说,到底是瞎猫碰到了死耗子,还是大佬过于社会呢