马拉车Manacher 最长回文子串

看的这家的详解

string Manacher(string s)
{
    string sNew = "$#";
    for (auto iter = s.cbegin(); iter != s.cend(); iter++)
    {
        sNew += *iter;
        sNew += "#";
    }
    int iNewSize = sNew.size();
    int iLength = -1;    // 最长回文子串的长度
    int iPos = -1; // 最长回文子串中心点的位置
    vector<int> p(iNewSize, 0);
    int id = 0;
    int mx = 0;

    for (int i = 1; i < iNewSize; i++)
    {
        if (i < mx)
            p[i] = min(p[2 * id - i], mx - i);
        else
            p[i] = 1;
        while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++; 
  // 最左边sNew[0]='$',最右边sNew[sNew.size()] = '\0',无需判断边界
        if (mx < i + p[i])  //更新mx和id
        {
            id = i;
            mx = i + p[i];
        }
        if (p[i] - 1 > iLength) //更新最大值
        {
            iLength = p[i] - 1;
            iPos = i;
        }
    }
    auto iStart = s.cbegin() + (iPos - iLength - 1) / 2; 
    return string(iStart, iStart + iLength);
}
posted @ 2019-07-25 19:51  Mr.doublerun  阅读(13)  评论(0)    收藏  举报