51Nod-1088-最长回文子串

来源:互联网 发布:襄阳seo搜索 编辑:程序博客网 时间:2024/05/11 21:36

51Nod-1088-最长回文子串

1088 最长回文子串回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。输入一个字符串Str,输出Str里最长回文子串的长度。Input输入Str(Str的长度 <= 1000)Output输出最长回文子串的长度L。Input示例daabaacOutput示例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-1while True:    try:        s = input()        print(Manacher(s))    except EOFError:        break
原创粉丝点击