最长公共子序列python实现,最长回文子串动态规划 python
1问题描述给定字符串S,求S最长回文列的长度。
根据2状态转移的思想,dp[i][j]表示从S[i]到S[j]表示的子串是否为回文子串,否则为1,否则为0。这样,根据S[i]是否等于S[j]就可以把转移情况分为两类。
当S[i]==S[j]时,只要S[i 1]到S[j-1]是回文子串,那么S[i]到S[j]就是回文子串;恰恰相反。如果S[i]!=S[j],S[i]到S[j]一定不是回文子串。这样就可以写出状态转移方程。
边界:dp[i][i]=1,dp[i][i 1]=(S[i]==S[i 1])?1 : 0。
另外还需要注意的是,如果按照I和J从小到大的顺序枚举substring的两端,然后更新dp[i][j],并不能保证计算出dp[i 1][j-1],所以不会得到正确的dp[i][j]。解决方法是按照子串的长度和子串的初始位置进行枚举。由于边界的原因,它表示长度为1和2的子列,每个转换都会将子列的长度减少2。
3558 www.sina.com/(时间复杂度可达o (n ^2)).
# include CST dio # includecstringconsintmaxn=1010;char S[MAXN];int DP[MAXN][MAXN];int main())gets);intlen=Strlen(s)、ans=1;SMS (DP,0,sizeof)DP);初始化//的DP序列(inti=0;ilenI))/边界DP[I][I]=1;if(Ilen-1)if)s[I]==s[I1]){ DP[I][I 1]=1;ans=2;//初始化时注意当前最长回文子串的长度} }//状态转移方程for(INTL=3;L=lenl()/枚举(inti=0;I L-1 len;I )//枚举子串int j=il-1的开始端点;//子串的右端点if(s[I]==s[j]DP[i1][j-1]==1){ DP[I][j]=1;ans=L;//更新最长回文子串长度}}printf(%d\n ,ans);0;} 3除了动态规划法,还可以通过混合列来求解,降低时间复杂度。
代码
hash+二分的思路
33558 www.Sina.com/# include iostream # include CST dio # include string # include vector # includealgorithmusingnamespace ttd tttd const LL MOD=1e 9 7;//MOD为计算混列值时的模量const LL P=1e7 19//P为计算混列值时的进制const LL MAXN=2e5 10//字符串的最大长度//powP[i]为P^i%MOD,H1和氘分别为潜艇用热中子反应堆(海底热反应堆的缩写)和rstr的混列值LL powP[MAXN]、H1[MAXN]、H2[MAXN];//初始化函数为powP函数void init(){ powP[0]=1;for(intI=1;IMAX ni){ powp[I]=(powp[I-1]* p)% MOD;} }//计算函数计算字符串潜艇用热中子反应堆(海底热反应堆的缩写)的混列值voidcalh(llh)、string str ) ) h(0)=str(0)。//H[0]单独处理for(inti=1;istr。长度(;I)h(I)=)h(I-1)* pstr)% MOD;}//calSingleSubH计算h[I.j]intcalsinglesubh[],int i,intj]{if(I==0)返回h[j];返回()h[j]-h[I-1]* powp[j-I1])% MOD MOD)% MOD;(//设对称点为我,字符串长度为莱恩,用[左,右]将回文半径一分为二)查找满足哈希尔==哈希尔的最后回文半径(/等效于查找满足条件的第一个哈斯尔!=哈希尔的回文半径,减少一即可//isEven集中的鸭子回文为0,求爱回文为1intbinarysearch(intleft,int right,int len,int i,int isEven)(while)))65//左半子串混杂值H1[H1L .H1R],右半子串值H2 [ h2l .h2r ] int h1l=I-midi seven)、INTH2L=Len-left-(Imid)、h2r=Len-left-(IIS even);intHashl=calsinglesubh(H1,H1L,H1R);intHashr=calsinglesubh(H2,H2L,H2R);如果(Hashl!=Hashr(right=mid;//哈希值各不相同,回文半径=mid else left=mid 1;//哈希值相等,回文半径mid } return left-1;//返回最大回文半径(} int main)){ init);字符串潜艇用热中子反应堆(submarine thermal reactor的缩写)获取线(CIN海峡);卡尔(H1海峡);恢复(str.begin)、str。end);//反转字符串并选择卡尔(H2海峡);int ans=0;//奇回文for(intI=0;istr。长度(;我()/二分钟上界在边界点我左右长度的小值上加上1intmaxlen=min(I,(int)str。长度)-1-I)1;intk=Binarysearch(0,maxLen,str.length),I,0);ans=max(ans,k * 2 ^ 1);//偶回文for(intI=0;istr。长度(;I ) ) /二分钟上界在边界点我左右长度的小值上加1 (注意左边的长度为i 1) intmaxlen=min(I1,(int)str。长度))-1-I)1;intk=Binarysearch(0,maxLen,str.length),I,1);ans=max(ans,k * 2);}printf(%d\n ,ans);返回0;}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。