Manacher算法,O(n)时间复杂度
算法内容:http://blog.csdn.net/xingyeyongheng/article/details/9310555
时间复杂度分析:http://www.zhihu.com/question/30226229
主要思想:
f[i] 表示以i为中心的最长回文串半径(包含i),考察f[i]与已算出的f[0]~f[i-1]的联系
设j<i,且j是使得j+f[j]最大的字符。当j+f[j]>i时,有f[i]>=min{f[2*j-i],f[j]+j-i};否则f[i]>=1.
使用‘#’分隔字符串从而把回文串的奇偶两种情形统一为奇数类回文串
基于上一点,以i为中心的原始最长回文串长度即为f[i]-1
具体实现
/***************************
http://hihocoder.com/problemset/problem/1032
Manacher算法 O(n)
***************************/
#include
#include
#include
using namespace std;
#define SIZE 2000002
int N, dp[SIZE];
char str[SIZE];
void solve();
void init()
{
cin >> N;
for (int i = 0; i < N; ++i)
{
cin >> str;
for (int j = strlen(str); j >= 0; --j)
{
str[(j << 1) + 1] = str[j];
str[j << 1] = '#';
}
solve();
}
}
void solve()
{
int i, m_s, m_i, max;
dp[0] = i = m_s = max = 1, m_i = 0;
while (str[i])
{
if (m_s > i)
dp[i] = min(dp[2 * m_i - i], m_s - i);
else
dp[i] = 1;
while (str[i - dp[i]] == str[i + dp[i]])
{
++dp[i];
if (i < dp[i]) break;
}
if (i + dp[i] > m_s)
{
m_i = i;
m_s = i + dp[i];
}
if (max < dp[i]) max = dp[i];
++i;
}
cout << max - 1 << endl;
}
int main()
{
init();
return 0;
}