5. 最长回文子串

题目描述

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

中间扩散法

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s)==1 or not s:
            return s
        max_r=1
        index_r=0
        new="#"+"#".join(s)+"#" 
        r=[1]*len(new) #储存每一个点扩散出去的半径
        for i in range(len(new)):
            while i-r[i]>0 and i+r[i]<len(new) and new[i-r[i]]==new[i+r[i]]:# 增加半径
                r[i]+=1
            if max_r<r[i]:
                max_r=r[i]
                index_r=i
        max_r-=1
        return new[index_r-max_r:index_r+max_r+1].replace("#","")

每两个元素之间都插入一个"#",这样子来避免奇数和偶数的分类讨论,只需要在结尾的时候消除所有的"#"就好了

执行用时 :4752 ms, 在所有 Python3 提交中击败了27.41%的用户
内存消耗 :13.5 MB, 在所有 Python3 提交中击败了31.66%的用户

中间扩散法—改

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s)==1 or not s:
            return s
        max_r=1
        index_r=0
        zd=1
        mx=0
        new="#"+"#".join(s)+"#" 
        r=[1]*len(new) #储存每一个点扩散出去的半径
        for i in range(len(new)):
            if i<max: #如果是在之前浏览过的地方
                if r[2*zd-i]<mx-i:#如果左边对应位置元素半径不超过大半径
                    r[i]=r[2*zd-i]
                else: #如果左边对应位置元素半径超过了大半径,需要对右边多出部分进行检验
                    r[i]=mx-i
                    while i-r[i]>0 and i+r[i]<len(new) and new[i-r[i]]==new[i+r[i]]:# 增加半径
                        r[i]+=1
            if i+r[i]>mx: #如果浏览到了没浏览过的,更新最近一次的中点和半径
                mx=i+r[i]
                zd=i

            if max_r<r[i]: #记录最长的回文子串中点和半径
                max_r=r[i]
                index_r=i
        max_r-=1
        return new[index_r-max_r:index_r+max_r+1].replace("#","")

多了一个对于对称点半径的使用,减少了计算的数量。

执行用时 :104 ms, 在所有 Python3 提交中击败了93.28%的用户
内存消耗 :13.3 MB, 在所有 Python3 提交中击败了31.71%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值