最长回文子串

本文介绍了两种寻找字符串中最长回文子串的方法:动态规划和Manacher算法。动态规划通过构建二维数组来记录子串状态,Manacher算法则通过预处理和中心扩展的方式高效求解。文章详细展示了算法实现过程。

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

  • 动态规划
class Solution:
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        if not s:
            return s
        count = 1
        tmp = s[0]
        nums = len(s)
        mark = [[0 for _ in range(nums)] for _ in range(nums)]
        for ii in range(nums):
            mark[ii][ii] = 1
        for i in range(2, nums+1):
            for j in range(nums-i+1):
                if i==2:
                    if s[j] == s[j + i -1]:
                        mark[j][i+j-1] = 1
                        if i > count:
                            tmp = s[j:j+i]
                else:
                    if s[j] == s[j + i -1] and mark[j+1][i+j-2]:
                        mark[j][i+j-1] = 1
                        if i > count:
                            tmp = s[j:j+i]
                    else:
                        mark[j][i+j-1] = 0      
        return tmp
  • manacher
class Solution:
    def longestPalindrome(self, s):
        if len(s) <= 1:
            return s
        mark = ['^', '#']
        for ele in s:
            mark.extend([ele, '#'])
        mark.append('$')
        table = [0] * len(mark)
        c = r = 0
        tmp = 0
        reuslt = []
        for i in range(1, len(table) - 1):
            # 这个地方得注意,i的mirror的左侧边界得大于c的左侧边界,不能小于或等于
            if i < r:
                table[i] = min(table[2*c - i], r - i)
            while mark[i - table[i] - 1 ] == mark[i + table[i] + 1 ]:
                table[i] += 1
            if table[i] > tmp:
                result = mark[i - table[i] : i + table[i] + 1]
                tmp = table[i]
            if i + table[i] > r:
                c = i
                r = i + table[i]
        return ''.join([ele for ele in result if ele != '#'])

感觉网上讲的manacher方法都有点省略。

整个判断应该如下,上面方法只不过是对下面的整理。

if i < r:
    if table[2*c - i] < r - i:
        table[i] = table[2*c - i]
    elif table[2*c - i] > r - i:
        table[i] = r - i
    else:
        table[i] = r - i
        while mark[i - table[i] - 1] == mark[i + table[i] + 1]:
            table[i] += 1
else:
    while mark[i - table[i] - 1] == mark[i + table[i] + 1]:
        table[i] += 1
  • 中心向两边扩散(感觉实现的有点累赘)
def broadcast(s):
    if len(s) <= 1:
        return s
    res = ''
    for i in range(len(s)-1):
        res1 = func(s, i, i)
        res2 = func(s, i, i+1)
        tmp = res1 if len(res1) > len(res2) else res2
        res = res if len(res) >= len(tmp) else tmp
    return res


def func(s, i, j):
    res = s[i] if i==j else s[i] + s[j]
    i -= 1
    j += 1
    while i >= 0 and j <= len(s)-1:
        if s[i] == s[j]:
            res = s[i] + res + s[j]
            i-=1
            j+=1
        else:
            break
    return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值