leetcode 5 Longest Palindromic Substring【manacher算法】

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

Input: "cbbd"
Output: "bb"

简单的写法是枚举中心点,然后向两侧扩张,时间复杂度O(n2)

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        mlen=0
        ml=-1
        mr=-1
        for i in range(len(s)-1):
            if s[i]==s[i+1]:
                l=i
                r=i+1
                while(l>=0 and r<=len(s)-1):
                    if(s[l]==s[r]):
                        l=l-1
                        r=r+1
                    else:
                        break
                if(mlen<r-l-1):
                    ml=l+1
                    mr=r-1
                    mlen=r-l-1
        for i in range(len(s)):
            l=i
            r=i
            while(l>=0 and r<=len(s)-1):
                if(s[l]==s[r]):
                    l=l-1
                    r=r+1
                else:
                    break
            if(mlen<r-l-1):
                ml=l+1
                mr=r-1
                mlen=r-l-1
        return s[ml:mr+1]

对象说初中有一次比赛遇到过,搞成字符串哈希,二分枚举可扩展的长度,比较哈希值是否相同,可以降到log(n),嗯……初中

log(n)还有一种想不开自己给自己挖坑的做法,然而我自己现在已经看不懂了再见

ural1297Palindrome【后缀数组+RMQ最长回文子串】

然后研究了一下时间复杂度O(n)的马拉车,先上代码。经历了若干PE之后终于A了

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        mlen=0
        mpos=0
        #mlen mpos维护的是对称的最右边的点,未必是对称最长的那个
        mx=0
        mcenter=0
        st=['@']
        for i in range(len(s)):
            st.append('#')
            st.append(s[i])
        st.append('#')
        p=[1]*len(st)
        for i in range(len(st)):
            if(mpos<i):
                p[i]=min(mx-i,p[2*mpos-i])
            else:
                p[i]=1
            while(i+p[i]<len(st) and i-p[i]>=0 and st[i+p[i]]==st[i-p[i]] ):
                p[i]=p[i]+1
            if(i+p[i]>mx):
                mx=i+p[i]
                mpos=i
            if(mlen<p[i]):
                mlen=p[i]
                mcenter=i
        return s[(mcenter-mlen)/2:(mcenter-mlen)/2+mlen-1]
                

先将'#'插入字符串中,这样就不用判断单数还是偶数(讲道理,第一种写法也可以这样写)

维护两个变量分别是目前回文串可扩展的最右的位置mpos和这个回文串的中心mpos

再维护两个变量目前回文串最长的半径mlen和中心点位置mcenter(要是只求长度就不用维护中心点)

参考这篇 https://www.cnblogs.com/grandyang/p/4475985.html






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值