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


相关推荐

  • 关于ActionContext.getContext()的使用方法心得

    关于ActionContext.getContext()的使用方法心得

    2021年12月6日
    44
  • 提交到svn服务器时,一直缓冲不,

    提交到svn服务器时,一直缓冲不,

    2021年9月20日
    49
  • 微信小程序开发框架和工具库推荐

    微信小程序开发框架和工具库推荐

    2022年3月13日
    121
  • unity3d C#语言基础(继承)

    继承1:子类可以继承父类的所有属性和方法,构造函数除外。2:子类只能访问父类用public和protected修饰的属性和方法。3:用sealed修饰的类不能被继承。4:子类调用父类带参构造方法的时候必须使用base,子类构造方法可以不带参数。5:子类重写父类方法时,父类同名方法用virtual修饰,子类同名方法用override修饰。6:子类访问父类同名方法时用base。

    2022年4月14日
    100
  • Python安装pymssql「建议收藏」

    Python安装pymssql「建议收藏」Python安装pymssql(v2.1.3)pymssql下载地址:https://pypi.python.org/pypi/pymssql/python2.7×32版本下pymssql的安装:如果使用2.1.1版本:https://pypi.python.org/pypi/pymssql/2.1.1#downloads,下载时选择pymssql-2.1.1.win32-py2.7.exe

    2022年6月15日
    148
  • kafka队列模式_redis消息队列和mq

    kafka队列模式_redis消息队列和mq一、消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ二、消息队列应用场景以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。2.1异步处理场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式a、串行方式:将注册

    2022年10月9日
    2

发表回复

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

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