zoukankan      html  css  js  c++  java
  • 马拉车算法总结

    【算法简述】

    马拉车(Manacher)算法是在O(n)时间内解决寻找源字符串的最长回文子串S的问题的算法。

    朴素算法情况下对于每一个S[i]都要左右遍历其最大回文子串,所以时间复杂度是O(n2

    【算法原理】

    充分利用之前求得的S【j】,为求S【i】服务。

    预处理:在每个字符左右两边插入#将字符串变成奇数串

    算法核心:

    p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;

    其中p[i]为S[i]的回文半径,mx为i之前某一回文串右侧最远延伸到的位置,id为该回文串的中心点位置,很显然从mx的对称点到mx这一段是关于id对称的。

    如何利用之前求得的s[j]来求s[i]的回文串长度呢?
    分情况讨论
    (1) 当 i在mx左侧,p[j] < mx - i,即S[j]的回文子串的左端点不会超过mx的对称点,那么很显然S[i]的回文子串的右端点不会超过mx,所以此时取P[i] = p[j]

    (2)当i在mx左侧, p[j] > mx - i时,即S[j]的回文子串的左端点超过mx的对称点,那么很显然S[i]的回文子串的右端点至少要到mx,至于mx右侧的,只能一个一个匹配以确定p[i]了。

    (3)当i在mx右侧,即i > mx,初始化p[i] = 1.这时候很显然,mx和id是要更新的。因为此时回文串右侧延伸的位置已经超过mx了。

    【模板】

     为了最后返回字符串的参数传入方便,在字符串加了#的基础上又加了$

    //返回源字符串S的最长回文子串 
    string Manacher(string s){
        //预处理源串 
        string t = "$#";
        for(int i=0; i<s.size(); i++){
            t+=s[i];
            t+="#";
        }
        //新建p数组,大小和t串一致,初始化为0 ,p[i]表示以t[i]为中心的回文串半径 
        vector<int> p(t.size() , 0); 
        
        //设定重要参数 mx(某回文串延伸到的最右边下标),id(mx所属回文串中心下标),
        //reCenter(结果最大回文串中心下标),reLen(最大长回文长度) 
        int mx = 0, id = 0, reCenter = 0, reLen = 0;
        
        //遍历t字符串
        for(int i=1; i<t.size(); i++){
            //核心算法 
            p[i] = mx > i ? min(mx - i , p[2*id - i]) : 1;
            
            //上面的语句只能确定i~mx的回文情况,至于mx之后的部分是否对称,就只能老老实实去匹配了,匹配一个p[i]++ 
            while(t[i + p[i]] == t[i - p[i]]) p[i]++;
            
            //当t[i]匹配的 右边界超过mx时mx和id就更新 
            if(i+p[i] > mx){
                mx = i+p[i];
                id = i;
            }
            //更新结果数据 
            if(p[i] > reLen){
                reLen = p[i];
                reCenter = i;    
            }
        }
        
        return s.substr((reCenter - reLen) / 2 , reLen - 1)  ;
        
    }
  • 相关阅读:
    KnowYoueSelf
    计算机组成原理--海明码的编码和校验方法(易懂)
    html5新特性
    web前端性能优化
    web标准
    《王者归来》笔记-安全&性能01
    vue核心最基本功能
    BOM&DOM
    JavaScript-语法
    前端04
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9705358.html
Copyright © 2011-2022 走看看