51Nod-1088-最长回文子串

本文介绍了51Nod-1088最长回文子串问题,探讨了两种解决方案:暴力解法和Manacher算法。暴力解法通过逐个检查所有可能的子串来确定最长回文子串;Manacher算法则更高效,通过一次扫描即可找到最长回文子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

51Nod-1088-最长回文子串

1088 最长回文子串

回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。
输入一个字符串Str,输出Str里最长回文子串的长度。

Input
输入Str(Str的长度 <= 1000)

Output
输出最长回文子串的长度L。

Input示例
daabaac
Output示例
5

解题方法
该题解题方法有两种,一种是直接暴力,一种是运用Manacher算法解题。

暴力解法是,每次规定一定的长度,然后判断等于该长度的所有子串是否有符合回文的。先从最长的长度开始遍历判断,依次递减,直到遇到符合条件的就停止。
但是暴力解法不适合数据过大的情况,而Manacher算法可以。

Manacher算法的讲解可以看这一篇博客——求字符串的最长回文子串
还有一篇是用python设计最长回文子串代码——Python算法实践——最长回文串


解题代码
暴力解法

#判断[l, r]区间的子串是否为回文字符串
def check(s, l, r):
    #m为反转字符串
    if l == 0:
        m = s[r::-1]
    else:
        m = s[r:l-1:-1]

    return m == s[l:r+1]

while True:
    try:
        s = input()
        ls = len(s)
        End = ans = 0

        #length为子串长度,l为子串左边界
        for length in range(ls, 0, -1):
            for l in range(ls-length+1):
                r = l + length - 1
                if check(s, l, r):
                    End = 1
                    ans = length
                    break
            if End:
                break
        print(ans)
    except EOFError:
        break

暴力很好理解,但是时间复杂度高,此代码在51Nod上跑了一千多ms,而Manacher算法仅仅只需要近百ms。
Manacher算法解法

def Manacher(s):
    #join是用于在s中插入#
    s = '*#' + '#'.join(s) + '#'
    ls = len(s)
    p = []
    #id为回文子串中心,mx为回文子串右边界,ans记录最长回文子串长度
    id = mx = ans = 0

    for i in range(ls):
        #pi记录以id(也是i)为中心的最大回文子串长度
        #首先利用对称性质找到以id为中心的最长回文子串长度
        pi = min(p[2*id-i], mx - i) if mx > i else 1
        #然后扩展两边去找回文子串
        while i+pi < ls and i-pi >= 0 and s[i+pi] == s[i-pi]:
            pi += 1
        # mx记录回文子串能触摸到的最大有边界
        if i+pi > mx:
            mx = i+pi
            id = i
        ans = max(ans, pi)
        p.append(pi)

    return ans-1

while True:
    try:
        s = input()
        print(Manacher(s))
    except EOFError:
        break
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值