本文主要介绍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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。