编码挑战
挑战:给定一个字符串。如何找到该字符串中最长的回文?

图:字符串'locoannamadam' ,包含多个回文。最长的回文是'madam' 。
为了便于理解,请允许我快速添加一个关于调色板的定义。
定义:回文是指一个前后读数相同的字符序列,如 , , 或 。'madam' 'anna' '101'
本文想在Python中给你一个快速而简单的解决方案。首先,我们将解决一个比较简单但重要的问题,即首先检查一个子串是否是宫格。
检查子串是否是回文
通过使用切片表达式word == word[::-1] ,你可以很容易地检查一个子串是否是回文,如果这个词向前和向后都是一样的,即是回文,那么它的评估值为True 。
接下来,我们将探讨如何在一个Python字符串中找到最长的子串,同时也是一个Palindrome。你可以在代码解决方案中找到我们的Palindrome检查器(突出显示)。
查找是帕林多姆的最长子串
寻找一个字符串中最长的宫格的粗暴方法是在一个嵌套的循环中遍历所有的子字符串。 [for](https://blog.finxter.com/python-loops/)循环中遍历所有子串。然后使用word == word[::-1] ,检查每个子串是否是一个回文。使用 中的函数跟踪最长的回文。 [len()](https://blog.finxter.com/python-len/)函数在if 。
这里是完整的解决方案。
def find_longest_palindrome(s):
longest = ''
n = len(s)
for i in range(n):
for j in range(i+1,n+1):
word = s[i:j]
if word == word[::-1]:
if len(word)>len(longest):
longest = word
return longest
print(find_longest_palindrome('locoannamadam'))
# madam
print(find_longest_palindrome('anna'))
# anna
print(find_longest_palindrome('abc'))
# a
运行时复杂度
这有立体的运行时间复杂性,即对于一个长度为n 的字符串,我们需要检查O(n*n) 不同的词。每个词可能有多达n 个字符,因此回文检查本身就是O(n) 。这样一来,运行时间复杂度为O(n*n*n) = O(n³) 。
讨论和更好的解决方案
这就是我们能做的最好的了吗?
不!我们在理论上能做到的最好的方法是线性的运行时间复杂度和线性的空间复杂度,称为Manacher的算法。这个想法是选择多个 "回文中心",并通过向左或向右添加字符来一步步地增长这些中心。
然而,在编码面试中,不指望你自己能想出这个办法。
二次方编程的想法
一些面试官可能希望你能想出一个 "动态编程 "的想法,即构建一个布尔矩阵。
数据结构:布尔矩阵的每个单元格(i,j) ,如果字符串s[i:j] 是 Palindrome,则为True ,否则为False 。True ,并具有最高值的单元格j-i ,代表最长的Palindrome。
算法:用布尔值填充数据结构。你可以通过检查较小的单词s[i+1:j-1] 是否是Palindrome,以及第一个和最后一个字符s[i] 和s[j] 是否相同,从而很容易地从较小的单元格中构建一个单元格。
下面是这个想法的快速概述。
