马拉车算法

  问题定义:求最大回文子串

相对暴力点的中心扩展算法理解起来很容易,就是依次遍历字符串,每个字符作为中心点向外扩展

这个马拉车算法其实就是在中心扩展算法上进行的改进,我们在用中心扩展算法判断以每个字符为中心的最长回文时,需要对每个字符两端分别开始扩展,依次判断,时间复杂度为O(N2),那么如何优化呢? 还是拿一个例子来说明吧,这样讲起来清楚一点:

假设字符串    c b e d e a e d a f c

可以看到最长回文为   d e a e d  它的半径为2(不算自身)。

当我们判断索引为7的 d 时,由于d关于中心a对成,且在a的半径范围内,根据对称性,那么d的半径就与前面的镜像d(索引为3)相同。

当然这里面的情况还要具体来讨论

具体解释参照

https://www.cxyxiaowu.com/2665.html

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s)<2:return s
        news ='#'+'#'.join(s)+'#'
        N = len(news)
        p = [0 for _ in range(N)] #p记录以该字符为中心的回文半径
        center, maxRight = 0,0
        maxLen,start = 0,0 #maxLen 最大回文长度,start 最大回文索引位置
        for i in range(N):
            if i < maxRight:
                mirror = 2*center-i
                p[i] = min(maxRight-i,p[mirror])  # 这个是最重要的
            left = i - (1+p[i])
            right = i+ (1+p[i])
            while left>=0 and right<N and news[left]==news[right]:
                p[i]+=1
                left-=1
                right+=1
            if i+p[i] > maxRight:
                maxRight = i+p[i]
                center = i
            if p[i] > maxLen:
                maxLen = p[i]
                start = (i-maxLen)//2
        return s[start:start+maxLen]

如果看不懂详解的话可以留言,到时候会更新这篇文章做个详细介绍。

原文地址:https://www.cnblogs.com/bianque/p/13549376.html