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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Linux挂载磁盘分区「建议收藏」

    Linux挂载磁盘分区「建议收藏」Linux系统一般都会有未挂载的磁盘,如果我们想使用这些为挂载的磁盘就需要挂载到指定目录才能使用。一、有多个磁盘,将未分区的磁盘挂载1、进入root用户su–2、查看已挂载磁盘的使用情况:df–h可以看到系统已经挂载了sda磁盘,并分为sda1、sda2、sda3,3个分区3、查看所有磁盘信息(包括未挂载磁盘):fdisk–l4、创建新的磁盘…

    2022年6月19日
  • C语言实现学生信息管理系统

    C语言实现学生信息管理系统使用C语言对学生管理系统进行优化

    2022年6月20日
  • 11 如何通过 “副本传输” 传输从DEV到QAS的请求号

    11 如何通过 “副本传输” 传输从DEV到QAS的请求号业务背景:在实际项目中,当顾问在DEV配置系统中做好配置,或者开发顾问在DEV开发系统中做好了开发,生成了请求号后,需要将对应的配置传输到QAS系统(集成测试系统),要想将请求号对应的配置或开发内容从DEV系统传输到QAS系统。常规操作就是需要将请求号进行释放后,在进行传输,但是在实际情况下,很多时候顾问的配置或开发内容并未全部完成或还需要进行局部修改的情况下,副本传输就可以解决既可以不释放请求号,又可以达到跨服务器传输请求号内容的目的了。PS:请求号一旦释放后,就不能再使用同一个请求号进行配置和

    2022年6月28日
  • JAVA四舍五入保留一位小数

    JAVA四舍五入保留一位小数newBigDecimal(speed).setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue()

    2022年5月11日
  • Python如何实现一个简单缓存_pytest conftest.py文件

    Python如何实现一个简单缓存_pytest conftest.py文件前言pytest运行完用例之后会生成一个.pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。方便我们在运行用例的时候加上–lf和–ff参数,快速运行上一

    2022年7月30日
  • 手把手教你制作网页导航栏

    手把手教你制作网页导航栏手把手教你制作网页导航栏众所周知,导航栏是网页的重要组成部分,本篇文章将会带你由浅入深的制作导航栏,子菜单,样式风格变化等。导航栏的重要部分——ul标签在导航栏中的文字,都是以无序列表ul和li标签实现的。下面通过几个小例子来为大家介绍如何实现网页导航栏的制作。1.用ul标签做一个简单般的菜单样式,首先在一个div盒子里创建一个无序列表,如图所示运行结果如下图所示:2.之后我们可以让列表横过来,需要用到css的浮动样式也就是float标签。我们需要让它向左浮动如图所示:运行结果如

    2022年7月22日

发表回复

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

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