LintCode 最长回文子串

2024-09-02 17:08
文章标签 最长 回文 子串 lintcode

本文主要是介绍LintCode 最长回文子串,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。

样例
给出字符串 “abcdzdcab”,它的最长回文子串为 “cdzdc”。

挑战
O(n2) 时间复杂度的算法是可以接受的,如果你能用 O(n) 的算法那自然更好。

第一次AC的连O(n2)都不是的,是O(n3),遍历所有子串。代码如下:

class Solution:"""@param: s: input string@return: the longest palindromic substring"""def longestPalindrome(self, s):# write your code heren=len(s)result=""m=0for i in range(n):for j in range(n-1,i,-1):if s[j]==s[i]:temp=s[i:j+1]res=self.judge(temp)if res>m:result=tempm=resif m<1:result=s[i]return resultdef judge(self,s):n=len(s)if n==0:return for i in range(n/2):if s[i]!=s[n-1-i]:return -1return n

然后参考了曾会玩的文章,感谢。
O(n2)的算法。利用回文串的对称性,从中心向两端扩展。对整个字符串来说,可能为中心的包括n个字符,和n-1个间隙,分两种情况来判断。代码如下:

class Solution:"""@param: s: input string@return: the longest palindromic substring"""def longestPalindrome(self, s):# write your code heren=len(s)result=""m=0for i in range(n):j=1temp=s[i]while(i-j>=0 and i+j<n ):if s[i-j]==s[i+j]:temp=s[i-j]+temp+s[i+j]j+=1else:breakprint tempif len(temp)>m:m=len(temp)result=tempfor i in range(1,n):j=1temp=""while(i-j>=0 and i+j-1<n):if s[i-j]==s[i+j-1]:temp=s[i-j]+temp+s[i+j-1]j+=1else:breakprint tempif len(temp)>m:m=len(temp)result=tempreturn result

O(n)的算法,manacher算法。相当于对O(n2)算法的改进,O(n2)在判断过程中重复判断了相同的子串,效率较低。
具体解析可以参考曾会玩的文章,我觉得解释的很棒,容易理解。需要注意的一点就是 回文半径和下标,处理起来要小心一点。代码如下:

class Solution:"""@param: s: input string@return: the longest palindromic substring"""def longestPalindrome(self, s):# write your code heret=ss='#'+'#'.join(s)+'#'n=len(s)dp=[0]*n    #记录回文半径right=0;    #当前所有回文子串能达到的最右端字符下标pos=0;    #以right为最右端的回文子串的中心字符下标for i in range(n):if i>=right:dp[i]=1 else:if i+dp[pos-(i-pos)]<=right: #s[i]关于s[pos]对称的s[pos-(i-pos)]的回文半径+i和right相比dp[i]=dp[pos-(i-pos)]else:dp[i]=right-i+1while(i+dp[i]<n and i-dp[i]>=0 and s[i+dp[i]]==s[i-dp[i]] ):dp[i]+=1if dp[i]>right:pos=iright=dp[i]return s[pos-(dp[pos]-1):pos+(dp[pos]-1)+1].replace('#','')

这篇关于LintCode 最长回文子串的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130557

相关文章

poj2406(连续重复子串)

题意:判断串s是不是str^n,求str的最大长度。 解题思路:kmp可解,后缀数组的倍增算法超时。next[i]表示在第i位匹配失败后,自动跳转到next[i],所以1到next[n]这个串 等于 n-next[n]+1到n这个串。 代码如下; #include<iostream>#include<algorithm>#include<stdio.h>#include<math.

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hihocoder1050 : 树中的最长路

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已。 但是不管怎么说,小Ho喜爱的玩具又升级换代了,于是他更加爱不释手(其实说起来小球和木棍有什么好玩的是吧= =)。小Ho手

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

计蒜客 Skiing 最长路

In this winter holiday, Bob has a plan for skiing at the mountain resort. This ski resort has MM different ski paths and NN different flags situated at those turning points. The ii-th path from the

PHP最长单一子串

<?php//方法一$s='abcccddddddcdefg';$max='';while($s!=''){$i=0; while($i<strlen($s) && $s[$i]==$s[0]) $i++;if ($i>strlen($max)){$max=substr($s,0,$i);} $s=substr($s,$i);}echo $m

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1