• 【算法日记】马拉车


    Manacher马拉车算法

    马拉车是时间复杂度为O(N)来求最长回文子串算法。

    神奇的事情:我从来没学过马拉车

    刷USACO题单刷到了马拉车

    马拉车第一步

    在字符中间加入未在字符串中出现的间隔符

    如 abba

    变 #a#b#b#a3

    这样无论字符串是奇串还是偶串,都可转为奇串的形式。

    对于数组 p[i],表示以t[i]字符为中心的回文子串的半径,若p[i] = 1,则该回文子串就是t[i]本身

    两个辅助变量mx和id,其中id为最大回文子串中心的位置,mx是回文串能延伸到的最右端的位置

    如果mx > i, 则 p[i] = min(p[2 * id - i], mx - i)

    否则, p[i] = 1

    当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于 i 和 j 对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 P[i] = P[j]

    当 P[j] >= mx - i 的时候,以S[j]为中心的回文子串不一定完全包含于以S[id]为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,就只能老老实实去匹配了。

    马拉车模板

    #include<iostream>  
    #include<string.h>
    #include<algorithm>  
    using namespace std;
    char s[1000];
    char s_new[2000];
    int p[2000];
    int Init()
    {
        int len = strlen(s);
        s_new[0] = '$';
        s_new[1] = '#';
        int j = 2;
        for (int i = 0; i < len; i++)
        {
            s_new[j++] = s[i];
            s_new[j++] = '#';
        }
        s_new[j] = '';   
    }
    int Manacher()
    {
        int len = Init();  //取得新字符串长度并完成向s_new的转换  
        int maxLen = -1;   //最长回文长度  
        int id;
        int mx = 0;
        for (int i = 1; i < len; i++)
        {
            if (i < mx)
                p[i] = min(p[2 * id - i], mx - i);  //需搞清楚上面那张图含义, mx和2*id-i的含义
            else
                p[i] = 1;
     
            while (s_new[i - p[i]] == s_new[i + p[i]])  //不需边界判断,因为左有'$',右有''  
                p[i]++;
            //我们每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率 
            if (mx < i + p[i])  
            {
                id = i;
                mx = i + p[i];
            }
            maxLen = max(maxLen, p[i] - 1);
        }
        return maxLen;
    }
    int main()
    {
        while (printf("请输入字符串:
    "))
        {
            scanf("%s", s);
            printf("最长回文长度为 %d
    
    ", Manacher());
        }
        return 0;
    }
    
  • 相关阅读:
    第03组 团队git现场编程实战
    第二次结对编程作业
    团队项目-选题报告
    第一次结对编程作业
    第一次编程作业
    软件工程第一次作业
    第09组 团队Git现场编程实战
    第二次结对编程作业
    团队项目-需求分析报告
    团队项目-选题报告
  • 原文地址:https://www.cnblogs.com/Shayndel/p/13983697.html
Copyright © 2020-2023  润新知