,,Python实现常见的回文字符串算法

,,Python实现常见的回文字符串算法

本文主要介绍Python常见的回文字符串算法。本文通过示例代码给大家详细介绍一下,有一定的参考价值,有需要的朋友可以参考一下。

回文

使用python自己的翻转函数reversed()

def is _ plalindrome(string):return string==' '。join(list(reversed(string)))`

自我实现

def is_plalindrome(string):

string=list(字符串)

length=len(字符串)

左=0

右=长度- 1

而左右:

if字符串[left]!=string[right]:

返回False

左=1

右-=1

返回True

最长的回文子串

暴力破解

暴力破解,枚举所有子串,判断每个子串是否为回文,时间复杂度为O(n ^ 3)

动态规划

定义解决方案:

s=列表

l=透镜

dp=[[0] * l for i in range(l)]

对于范围(l)中的I:

dp[i][i]=真

k=2时使用

dp[i][i - 1]=真

resLeft=0

resRight=0

#枚举子串的长度

对于范围(2,l ^ 1)中的k:

#子字符串的开始位置

对于范围内的I(0,l-k 1):

j=i k - 1

如果s[i]==s[j]和dp[i 1][j - 1]:

dp[i][j]=真

#保存最长的回文开始和结束点

如果resRight - resLeft 1 k:

resLeft=i

resRight=j

返回“”。join(s[resLeft:resRight 1])

时间复杂度为O (n 2),空间复杂度为O (n 2)

Manacher 算法

Manacher算法首先对字符串进行预处理,使所有的字符串都是奇数长度,并且插入相同的符号,该符号在原字符串中不存在,因此字符串的回文不受影响。

aba=# a # b # a # abab=# a # b # a # b #

我们称回文串中最右边的位置与其对称轴之间的距离为回文半径。Manacher算法定义了一个回文半径数组RL,RL[i]表示以第I个字符为对称轴的回文半径。对于上面得到的插入了分隔符的字符串,我们可以得到RL数组。

字符:# a # b # a #

RL: 1 2 1 4 1 2 1

RL-1: 0 1 0 3 0 1 0

i: 0 1 2 3 4 5 6

char: # a # b # a # b #

RL: 1 2 1 4 1 4 1 2 1

RL-1: 0 1 0 3 0 3 0 1 0

i: 0 1 2 3 4 5 6 7 8

我们还发现RL[i]-1:我们发现RL[i] -1正好是初始字符串中以位置I为对称轴的最长回文长度。

下面是获取RL数组的方法。你可以参考这篇文章(很清楚)

下面是算法实现

def manacher(preS):

s='#' '# '。加入(preS) '# '

l=透镜

RL=[0] * l

maxRight=pos=maxLen=0

对于范围(l)中的I:

如果我maxRight:

RL[i]=min(RL[2*pos - i],maxRight-i)

否则:

RL[i]=1

而i - RL[i]=0和i RL[i] l和s[i - RL[i]]==s[i RL[i]]:

RL[i]=1

如果我RL[i] - 1 maxRight:

maxRight=i RL[i] - 1

pos=i

maxLen=max(RL)

idx=RL.index(maxLen)

sub=s[idx - maxLen 1: idx maxLen]

return sub.replace('# ','')

空间复杂度:在辅助阵列的帮助下,空间复杂度为O(n)

时间复杂度:虽然内层有一个循环,但是内层的循环只在不匹配的部分执行,每个字符只执行一次,所以时间复杂度为O(n)

最长回文前缀

所谓前缀,就是从第一个字符开始。

以下最长的回文前缀

abbabbc=abbc

abababb=ababa

搜狗=s

如果原字符串反过来,那么问题就变成了寻找与原字符串前缀相同、后缀最长的值。这个问题实际上是KMP算法中下一个数组的求解。

解决方法:将原字符串反转拼接成原字符串,用' # '分隔原字符串,避免内部字符串的干扰。

def longest _回文_前缀:

如果不是s:

返回0

s=s '#' s[:-1] '$ '

i=0

j=-1

nt=[0] * len

nt[0]=-1

而i len(s) - 1:

如果j==-1或s[i]==s[j]:

i=1

j=1

nt[i]=j

否则:

j=nt[j]

return nt[len(s) - 1]

添加字符以生成最短的回文字符串。

这个问题其实和之前的基础书一样,

示例:

aacecaaa-aacecaaa #添加一个

Abcd-dcbabcd #添加dcb

我们先找到字符串最长的回文前缀,然后把字符串的其余部分反过来拼接到字符串的头部,这就是问题的所在。

定义解决方案:

长度=最长回文前缀

返回s[长度:][:-1] s

最长回文子序列

动态规划法

Dp[i][j]代表子序列s[I]中存在的最长回文子序列长度.j]

初始化dp[i][i]=1

当s[i]==s[j]为真时,dp[i][j]=dp[i 1][j-1] 2

当s[i]==s[j]为假时,DP [i] [j]=max (DP [i 1] [j],DP [i] [j-1])

#找出最长回文子序列的长度

定义解决方案:

l=透镜

dp=[[0] * l for i in range(l)]

对于范围(l)中的I:

dp[i][i]=1

#枚举子串的长度

对于范围(2,l ^ 1)中的k:

#枚举子串的起始位置

对于范围内的I(0,l-k 1):

j=i k - 1

如果s[i]==s[j]:

dp[i][j]=dp[i 1][j - 1] 2

否则:

dp[i][j]=max(dp[i][j - 1],dp[i 1][j])

返回dp[0][l-1]

时间复杂度为O (n 2),空间复杂度为O (n 2)

总结

以上是边肖介绍的用Python实现的常见回文字符串算法。希望对你有帮助。如果您有任何问题,请给我留言,边肖将及时回复您。非常感谢您对我们网站的支持!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: