最长回文子串

    xiaoxiao2025-01-10  6

    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; }

    转载请注明原文地址: https://ju.6miu.com/read-1295355.html
    最新回复(0)