LeetCode:最长回文子串

About

我感觉这道题应该是比较经典的题了,甚至有专门解此题的算法,虽然这是一道中等难度的题,但是该题却困扰了我一天(TAT),没办法,菜是原罪,现将解体经过整理如下

求字符串的最长回文子串

题目描述

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

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring

解题思路

刚开始解题时采用一贯思路,从头开始遍历字符串,写出来的算法直接超时,后来受评论区提出的中心扩展法启发,终于有了思路

  • 回文字符串是关于自己中心对称的,所以我们的思路是从子串的中心点去扩展,如果距离中心距离相等的两个点的值相等,那么就继续往下扩展。
  • 如果一个字符串的长度为n,那么中心点应该有2n-1个。
  • 如果从父字符串的中心开始遍历则时间复杂度最佳情况为O(n),所以我们选择从父字符串的中心往两边遍历中心点

代码如下(Python3)

import math, numpy

class Solution:
    def check(self, s: str, index: float) -> bool:
        '''
        从中心点开始扩散,找到基于该中心点的最长子串
        :param s: 父字符串
        :param index: 中心点在父字符串的索引
        :return: 回文子串
        '''
        res = ''
        Range = int(index) + 1 if int(index) < len(s) - math.ceil(index) else len(s) - math.ceil(index)
        for counter in range(Range):
            if s[math.floor(index - counter)] == s[math.ceil(index + counter)]:
                res = s[math.floor(index - counter): math.ceil(index + counter) + 1]
            else:
                return res
        return res

    def longestPalindrome(self, s: str) -> str:
        '''
        从父串的中心开始遍历
        :param s: 输入的父串
        :return: 最长回文子串
        '''
        res, temp = [], []
        length = len(s)
        if length <= 1:
            return s
        for index in numpy.arange(0, (length-1)/2, 0.5):
            if len(self.check(s, (length-1)/2 - index)) > len(self.check(s, (length-1)/2 + index)):
                temp = self.check(s, (length-1)/2 - index)
            else:
                temp = self.check(s, (length-1)/2 + index)
            if len(temp) > len(res):
                res = temp
            if len(res) >= (length/2 - index) * 2:
                return res
        return s[0]

运行结果

运行结果

很明显,算法性能不佳,一部分是语言的原因(Java最快的14ms),当然更多的是我这算法设计的不行

解法2

看了精选题解的算法,动态规划算法最普适,但是时间复杂度太高,性能不及我的算法,性能最好的”马拉车算法“没看懂(TAT),于是又冒出一个新的想法
思路:
上面的写法我感觉还可以改进,比如:从中心一步步扩展,到底还是需要遍历这个字符串,但是如果我们不去比较单个元素,直接比较字符串呢,然后利用二分法快速迭代到不相等的点,然后根据该点的索引对字符串进行切片,简直不要太快,哈哈哈哈哈哈啊哈哈哈。伪代码如图所示:

辣鸡手稿

即先判断abcd = eecd?相等了就返回,不相等再判断cd = cd?如果相等再判断bcd = ecd?,不相等就返回cddc,相等就返回bcdecd
但是,但是!!!由于我太菜了,其中索引值半天算不好,递归也没学好,55555写了两个小时没写出来遂作罢,希望有缘人看到我的想法能帮我实现一下谢谢~~~~~

你可能感兴趣的:(LeetCode:最长回文子串)