zoukankan      html  css  js  c++  java
  • 力扣leetcode5.最长回文子串

    简单的中心扩散算法,就不再赘述,但是看了官方题解中的马拉车,想到,其实中心扩散是可以优化到on时间复杂度的,尤其是在大数量级字符串时,先上对比图,字符串长度为100w和1000w,随机非回文长度和回文长度为1k、1k和1w、1w,上下分别为笔者算法和马拉车算法

    思路就是,如普通中心扩散算法一样,仅遍历一遍,但既然是求最长回文串,那么长度不需要回退,记录下当前最长的半径长度,在遍历下一个字符时,(重点1)直接套用最长半径,然后判断半径内的字符是否对称,然后从最长半径开始增长(重点2)如果从中心点开始扩张,那会走很多弯路,因为绝大部分情况下,是无法扩张到最长半径的,因此,从最长半径往中心点开始检测,在数据量足够大或者字符类型足够多时,非回文串的相同的概率越低,效果越显著,下图是60个随机ascii字符的运行时间,单位s

     1 class Solution(object):
     2     def longestPalindrome(self, s):
     3         len_longest = 0
     4         left = 0
     5         right = 0
     6         radius = 0
     7         if 1 == len(s) or 0 == len(s):
     8             return s
     9 
    10         temp_symmetry = [s[0], s[1]]
    11 
    12         len_s = len(s)
    13         for i in range(len_s):
    14             if i + 1 < len_s:
    15                 if s[i] == s[i + 1]:
    16                     [temp_left, temp_right, temp_len, temp_radius] = self.handle(s, i, i + 1, radius)
    17                     if temp_len > len_longest:
    18                         len_longest = temp_len
    19                         left = temp_left
    20                         right = temp_right
    21                         radius = temp_radius
    22 
    23             if i >= 2:
    24                 if temp_symmetry[0] == s[i]:
    25                     [temp_left, temp_right, temp_len, temp_radius] = self.handle(s, i - 1, i - 1, radius)
    26                     if temp_len > len_longest:
    27                         len_longest = temp_len
    28                         left = temp_left
    29                         right = temp_right
    30                         radius = temp_radius
    31                 temp_symmetry.pop(0)
    32                 temp_symmetry.append(s[i])
    33 
    34         # print(left)
    35         # print(right)
    36         print(radius)
    37         return s[left:right + 1]
    38 
    39     def handle(self, s, left, right, radius):
    40         right = right + radius
    41         left = left - radius
    42         len_left = left
    43         len_right = len(s) - right - 1
    44 
    45         if len_left < 0 or len_right < 0:
    46             return [-1, -1, -1, -1]
    47 
    48         for i in range(0, radius + 1):
    49             if s[left + i] != s[right - i]:
    50                 return [-1, -1, -1, -1]
    51 
    52         if 0 == len_left and 0 == len_right:
    53             return [left, right, right - left + 1, radius]
    54 
    55         len_min = min(len_left, len_right)
    56         ori_left = left
    57         ori_right = right
    58         for i in range(1, len_min + 1):
    59             if s[ori_left - i] == s[ori_right + i]:
    60                 left -= 1
    61                 right += 1
    62                 radius += 1
    63             else:
    64                 break
    65         return [left, right, right - left + 1, radius]
  • 相关阅读:
    python学习笔记Day3
    python学习笔记Day2
    IIS7.5部署除静态页面外都是404的解决方案
    CommandBehavior.CloseConnection有何作用
    没事别老待在家里
    冻结表格行列的思路
    如何构建逻辑清晰的可拖拽树的数据结构
    “仅次于20年前的最好的时间是现在“
    java的静态代理和2种动态代理(未完,待续)
    i++和++i
  • 原文地址:https://www.cnblogs.com/Pyrokine/p/12293271.html
Copyright © 2011-2022 走看看