最长回文子串—动态规划和Manacher算法(0(n)时间复杂度

动态规划:
dp[i][j] = 1  i==j
dp[i][j] = dp[i+1][j-1] + 2   str[i] == str[j]
dp[i][j] = max(dp[i+1][j], dp[i][j-1])  str[i] != str[j],不相等,等于前面的的最大值
   由于计算第i个位置,需要第i+1 个位置,因此倒着计算

Manacher 

http://blog.csdn.net/avenger_tao/article/details/51056159

#include <iostream>
#include <string>
#include <vector>
using namespace std;
/**
 * Manacher O(n)
 * @param string str
 */
int manacher(string &str) {
    int length = str.size() * 2 + 1;
    string cur_str(length, '#');
    // 字符串中间 插入 特殊字符
    for (int i = 0; i < length; ++i) {
        cur_str[i] = (i % 2 == 1 ? str[(i+1)/2 - 1] : '#');
    }
    cout << cur_str << endl;
    vector<int> RL(length, 0); // 每一个位置的回文串 长度 (不包含特殊字符)
    int maxLength= 0; // 最大长度
    int pos      = 0; // 当前最大字串对称位置
    int maxRight = 0; // 当前最大字串所能到达的最右边
    for (int i = 0; i < length; ++i) {
        if (i >= maxRight) {
            RL[i] = 1; // 超出最右位置,与之前的对称串没有关系
        } else {
            // 当前位置 在最大回文串里面(maxRight 左边)
            int j = 2 * pos - i; // i 关于pos对称的j (j 以及求过)
            RL[i] = min(RL[j], maxRight - i);
            /* 因为 maxRight - i 的最大值是 maxRight - pos
             * RL[j] 的 maxRight 如果超过pos,则肯定取 maxGight-i
             */
        }
        while (i - RL[i] >= 0 && i + RL[i] < length && cur_str[i-RL[i]] == cur_str[i+RL[i]]) {
            RL[i]++;
        }
        // 对称位置i + 回文串长度 (回文串长度 在cur_str里面是对称半径长度)
        if (RL[i] - 1 + i > maxRight) {
            maxRight = RL[i] + i - 1;
            pos = i;
        }
        maxLength = max(maxLength, RL[i]);
    }
    return maxLength - 1;
}
/**
 * 动态规划, O(n^2)
 */
int dpAlgorithm(string &str) {
    int length = str.size();
    vector<vector<int> > dp(length, vector<int>(length, 0));
    for (int i = length - 1; i >= 0; i--) {
        dp[i][i] = 1;
        for (int j = i + 1; j < length; ++j) {
            if (str[i] == str[j]) {
                dp[i][j] = dp[i+1][j-1] + 2;
            } else {
                dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
            }
        }
    }// end for
    return dp[0][length-1];
}
int main()
{
    string str;
    while (cin >> str) {
        cout << dpAlgorithm(str) << endl;
        cout << manacher(str) << endl;
    }
    return 0;
}
    原文作者:动态规划
    原文地址: https://blog.csdn.net/zhidao_wenge/article/details/60336420
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞