Python 求解最长回文子串

系统 1384 0

前言

题目来源:

            
              记得一副有趣的对联: "雾锁山头山锁雾, 天连水尾水连天", 上联和下联都是回文的.
当然类似的还有: "上海自来水水来自海上, 山西悬空寺寺空悬西山".
回文是什么意思? 就是把内容反过来读也是和原来一样的, 譬如 abccba, xyzyx, 这些都是回文的.
然而我们更感兴趣的是在一个英文字符串 L 中, 怎么找出最长的回文子串.
例如 L = "caayyhheehhbbbhhjhhyyaac", 那么它最长的回文子串是 "hhbbbhh".
这个任务看似简单, 但是如果我告诉你 L 的长度可能会接近 10^4, 问题似乎就变麻烦了.
不管怎么说, 加油吧骚年.

            
          

实战分析

网上关于最长回文子串的题型主要包括输出最长回文子串,又或者输出最长回文子串的长度,相对而言,后者更为简单。关于求解方法主要有四种,其一为暴力求解,最为直观,不过时间复杂度也是最大的;其二为动态规划求解,时耗稍微好一点,关于动态规划案例分析,有兴趣的朋友可以去动态规划学习(Python)了解一下;其三是中心扩展;其四是 Manacher 法。关于后两种方法可前往最长回文子串 Python 四种解法进行学习。

本文主要是从另个角度来对题目进行求解,和中心扩展法很像,但是时间复杂度更小。

            
              # L1 = 'caayyhheehhbbbhhjhhyyaac'
# L = 'aabbbaa'
L1 = 'babadcac'

def longestPalindrome():
    '''
    中心扩展
    :return:
    '''
    global L1

    L = L1 + '#'

    maxlen = 0
    start = 0
    start_index_list = []#考虑到最长回文子串存在多个值,这里记录多个起点的索引
    index_dict = {}#用于存放字符串中每个字符连续出现的次数以及起始索引
    for i in range(len(L)):
        if i >= sum(index_dict.values()):
            for j in range(i+1,len(L)+1):
                if len(set(L[i:j])) != 1:
                    index_dict[i] = len(L[i:j-1])
                    break

    for k,v in index_dict.items():
        i = k - 1
        j = k + v
        while i >= 0 and j < len(L):
            if L[i] == L[j]:
                if maxlen < j - i + 1:
                    maxlen = j - i + 1
                    start = i
                elif maxlen == j - i + 1:
                    start_index_list.append(i)
                i -= 1
                j += 1
            else:
                break

    start_index_list.insert(0,start)
    if maxlen >= 2:
        return [L[index:index+maxlen] for index in start_index_list]
    return None

            
          

输出结果为:

            
              ['hhbbbhh']
['bab', 'aba', 'cac']

            
          

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论