defgetExpandLength(left, right, s): ''' 中心展开求回文字符串长度 ''' while left >= 0and right < len(s) and s[left] == s[right]: left -= 1 right += 1 return right - left - 1
while left < len(s): for i inrange(left+1, len(s)): if s[i] == start_c: is_palindrome = True sub_str = s[left:i+1] sub_str_len = len(sub_str) # 检车是否为回文字符 iflen(sub_str)%2==0: # 偶数 mid = int(sub_str_len/2) front = sub_str[:mid] back = sub_str[mid:] else: # 奇数 mid = int(sub_str_len/2) front = sub_str[:mid] back = sub_str[mid+1:] mid_length = len(back) # for j in range(len(back)-1, 0, -1): for j,v inenumerate(front): if v != back[mid_length-1-j]: is_palindrome = False if is_palindrome: sing_palindrome = False if sub_str_len > max_palindromes_length: max_palindromes_length = sub_str_len max_palindromes = sub_str left += 1 if left < len(s): start_c = s[left]
if sing_palindrome: return s[0] else: return max_palindromes
classSolution: defgetExpandLength(self, left, right, s): ''' 中心展开求回文字符串长度 ''' # 假设输入的是left=4 right=6 s='babcbabcba' => 以i=5为中心向两边搜寻 # 0 1 2 3 4 5 6 7 8 9 # b a b c b a b c b a # 则 left = 3/2/1 和 right = 7/8/9 可构成回文 a b c b a b c b a # 此时当left再减少时 left=0 满足条件 right=10=len(s) 就不满足条件了 while循环结束 然后返回回文直径为 rigth - left - 1(i=5的中心点不计算在内) = 10-0-1 = 9 则半径为9//2=4向下取整 while left >= 0and right < len(s) and s[left] == s[right]: left -= 1 right += 1 return right - left - 1
deflongestPalindrome(self, s: str) -> str: iflen(s) < 2: return s s = '#' + '#'.join(list(s)) + '#' p = [0for x inrange(len(s))] max_id = -1 max_radius = -1 c = -1 mx = -1 for i inrange(len(s)): if i > mx: radius = self.getExpandLength(i, i, s) // 2 p[i] = radius c = i mx = i + radius # mx = c + p[c] / min = c - p[c] if radius > max_radius: max_id, max_radius = i, radius else: j = 2*c - i if j - p[j] > 2 * c - mx: # 在C的radius范围内 p[i] = p[j] elif j - p[j] < 2 * c - mx: # 越界了 p[i] = mx - i else: # 如果不是上述两种情况 就说明j-p[j]==min,依赖之前的有效信息,以及无法为当前以i为回文中心,寻找最长回文字符半径提供依据,所以要调用getExpandLength方法,用中心拓展的方法手动扩展回文半径 radius = self.getExpandLength(i-p[j]-1, i+p[j]+1, s) // 2 p[i] = radius if i + radius > mx: # 如果以当前i所在位置为回文中心,其右边大于原来以c所在位置为回文中心的右边,则更新其回文中心为c,mx修正为新的右边 mx = i + radius c = i mx = i + radius if radius > max_radius: # 如果新的回文半径大于原max_radius 就更新新的radius max_id, max_radius = i, radius return s[max_id-max_radius:max_id+max_radius+1].replace('#', '')
if __name__ == "__main__": solution = Solution() for i inrange(len(s)): print("-"*50) result = solution.longestPalindrome(s[i]) # print(result) # print(Answer[i]) print(result==Answer[i])