python最长回文子串动态规划_最长回文子串问题

python最长回文子串动态规划_最长回文子串问题问题描述回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。输入一个字符串Str,输出Str里最长回文子串的长度。方法一:暴力求解遍历每一个子串,再判断这个子串是不是回文串,最后判断这个串是不是最长的回文子串。遍历子串的复杂度是O(n^2),判断是不是回文串的复杂度是O(n),所以这个算法的复杂度是O(n^3)。方法二:动态规划法用一个二维的数组ai来表示从第i位到第j位的子…

大家好,又见面了,我是你们的朋友全栈君。

问题描述

回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。

输入一个字符串Str,输出Str里最长回文子串的长度。

方法一:暴力求解

遍历每一个子串,再判断这个子串是不是回文串,最后判断这个串是不是最长的回文子串。

遍历子串的复杂度是O(n^2),判断是不是回文串的复杂度是O(n),所以这个算法的复杂度是O(n^3)。

方法二:动态规划法

用一个二维的数组ai来表示从第i位到第j位的子串是不是回文串,在判断从i到j的子串是不是回文串时,可以先看i+1到j-1是不是回文串,再判断i位和j位是不是相同。这个算法中,遍历子串的复杂度仍然是O(n^2),但是判断是不是回文串的复杂度降到了O(1),所以这个算法的复杂度是O(n^2)。但是这个算法占据了O(n^2)的空间。

方法三:中心扩展法

顾名思义,任何一个回文串都有一个对称轴,从这个中心的位置开始,向两边扩展,可以得到以此为中心的最长回文串。但是要注意,这个对称轴的位置,可能是一个字符,也可能是两个字符中间。遍历对称轴的位置,复杂度是O(n),找到以此对称轴为中心的最长回文串,其复杂度是O(n),所以此算法的复杂度是O(n^2)。这个算法比动态规划好的地方是其空间复杂度只有O(1)。

#include

#include

using namespace std;

#define LEN 1000

int main(){

char str[LEN];

cin>>str;

int len=strlen(str);

int maxlen=0,mx;

for(int i=0;i

mx=1;

for(int j=1;(i-j>=0)&&(i+j

if(str[i-j]==str[i+j])

mx+=2;

else break;

}

maxlen=maxlen>mx?maxlen:mx;

}

for(int i=0;i

mx=0;

for(int j=0;(i-j>=0)&&(i+j+1

if(str[i-j]==str[i+j+1])

mx+=2;

else break;

}

maxlen=maxlen>mx?maxlen:mx;

}

cout<

return 0;

}

方法四:manacher算法

预处理

在字符串的开始加上一个’$’符,然后在每个字符中间插上一个’#’。比如,字符串ss=’abac’,处理之后是str=’$#a#b#a#c#’。接下来的计算针对处理后的字符串。

len数组

然后定义一个len数组,len[i]表示的是以str[i]为中心的最长回文串的半径。

仍以上面的字符为例。str=’$#a#b#a#c#’,以str[0]为中心的最长回文串是’$’,其半径是1;以str[4]为中心的最长回文串是’#a#b#a#’,其半径是4;len数组为{1,1,2,1,4,1,2,1,2,1}。可以发现,len[i]-1的值,就是原字符串ss中对应的回文串的长度(以#为中心的是偶长度的回文串,以字符为中心的是奇长度的回文串)。

计算len数组

算法的关键在于在计算len数组时,可以利用前面的结果进行优化。

引入变量maxright表示当前访问到的所有回文子串,所能触及的最右一个字符的位置;同时记录maxright所对应的回文串的对称轴的位置,记为pos。

复杂度分析

考虑p的值的变化,在计算的过程中,p只会增加不会减少,当p增加到strlen(str)时,每个位置的len数组的值都可以立即计算得出。所以算法的复杂度是O(n)。

#include

#include

#include

using namespace std;

#define N 100004

string str,ss;

int len[2*N+1];

int main()

{

cin>>ss;

str=”$#”;

for(unsigned int i=0;i

{

str+=ss[i];

str+=”#”;

}

// cout<

int pos=0,p=0,j=0;

len[0]=1;

for(unsigned int i=1;i

{

j=2*pos-i;

if(p>i)

len[i]=(len[j]>p-i)?(p-i):(len[j]);

else

len[i]=1;

while(i+len[i]=0&&str[i+len[i]]==str[i-len[i]])

len[i]++;

if(i+len[i]>=p)

{

pos=i;

p=i+len[i];

}

}

int ans=0;

for(int i=0;i

{

// cout<

ans=(len[i]-1>=ans)?len[i]-1:ans;

}

// cout<

cout<

return 0;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137462.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 解决mysql操作1045错误,1153错误和1130错误

    解决mysql操作1045错误,1153错误和1130错误

    2021年9月26日
    52
  • Linux命令 – su命令

    Linux命令 – su命令Linux命令-su命令  su是swithuser的缩写,在Linux中su命令可让用户暂时变更登入的身份,除root外变更时须输入所要变更的用户帐号与密码。1.语法:su[参数][-][用户帐号]2.功能:  变更用户身份,若不指定用户帐号,则预设变更为root。3.参数:-c<指令>或–command=<指令> 执行完指定的指令后,即恢复原来的身份。-f或–fast 适用于csh与tsch,使shell不用去读取启动文件。–l

    2025年6月2日
    1
  • Uart接口TTL电平详解

    Uart接口TTL电平详解Uart接口的详细解释我面试的时候一般喜欢问应聘者一个问题:UART与RS232/RS485的区别与联系?很多人对于这个问题答得都不是很好。还有些人压根就没有想过这个问题,一直认为他们是同一个东西,就是咱们俗称的串口。我刚入嵌入式的大门时,对这个问题也困惑过很久,后来终于弄明白了。跟大家一起分享一下吧。简单来说,区别在于UART是一种接口,而RS232/RS485是一…

    2025年11月15日
    3
  • 在线css三角形生成器 「干货」[通俗易懂]

    在线css三角形生成器 「干货」[通俗易懂]为了提高前端开发效率,笔者先后写了上百个前端工具,有些是给公司内部使用的,有些单纯是因为自己太“懒”,不想写代码,所以才“被迫”做的.接下来介绍的一款工具——css三角形生成器也是因为之前想要解放设计师的生产力,自己又懒得切图或者写css代码,所以想来想去还是自己做一个能自动生成css三角形代码的工具吧.接下来笔者就来带大家介绍一下这个工具的用途和实现方案,方便大家后续可以扩展出更多的“懒人工具”.在线css三角形生成器预览由预览动画我们可以看到通过在线工具我们可以轻松配置..

    2025年6月15日
    3
  • 微软的远程桌面RD client_rdclient远程桌面app

    微软的远程桌面RD client_rdclient远程桌面app一、下载RDClient这个就不用多说了。。。二、设置PC允许远程桌面连接PC系统以win10为例:1、进入“远程设置”允许远程协助与远程桌面连接桌面右键单击“此电脑”,属性,单击左边“远

    2022年8月6日
    4
  • mybatis的逆向工程怎么实现_列举创建连接的方法

    mybatis的逆向工程怎么实现_列举创建连接的方法Mybatis逆向工程创建方法1.首先利用数据库的可视化工具新建一张表。2.打开IDEA新建一个项目。3.导入pom.xml所需要的依赖文件。&amp;lt;?xmlversion=&quot;1.0&quot;encoding=&quot;UTF-8&quot;?&amp;gt;&amp;lt;projectxmlns=&quot;http://maven.apache.org/POM/4.0.0&quo

    2022年8月21日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号