求字符串中的回文最大长度

原创 2016年08月31日 15:49:13

目前,此问题最好的解法是Manacher算法,时间复杂度为O(n),本文还给出了另外两种便于理解的方法。

1.Manacher算法

//Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 
#include <iostream>
#include <algorithm>
using namespace std;

int Manacher(const string &data, const int &num)
{
	int len=num*2+1;//如:*1*2*3*
	string str(len,'*');
	for(int i=0;i<num;++i)
		str[2*i+1]=data[i];
	int *p=new int[len]();
	int mx = 0, id = 0;//mx表示0~(i-1)元素的最远右端;id表示具有最远右端中心元素点 
	for (int i = 1; i<len; ++i)
	{
	    p[i] = mx > i ? min(p[2*id-i], mx-i+1) : 1;
	    while (str[i + p[i]] == str[i - p[i]]) p[i]++;
	    if (i + p[i] > mx) 
		{
	        mx = i + p[i]-1;
	        id = i;
	    }
	}
	int res=*max_element(p,p+len);
	delete p;	
	return res-1;
}

int main()
{
	string str="12321476789987678998";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<Manacher(str,length)<<endl; 
}

2.暴力法(用到Manacher算法)思想

/*通过插入*来求最大回文长度,此时,最大回文长度为回文半径-1*/
#include <iostream>
#include <algorithm>
using namespace std;

int Manacher(const string &data, const int &num)
{
	int len=num*2+1;//如:*1*2*3*
	string str(len,'*');
	for(int i=0;i<num;i++)
		str[2*i+1]=data[i];
	int max_r=0;//记录最大半径 
	for (int i = 1; i<len-1; ++i)
	{ 
		int r=0; 
	    while ((i - r >= 0)&&(i + r <= len-1)&&(str[i + r] == str[i - r])) 
			r++;
	    if(r>max_r) max_r=r;
	} 	
	return max_r-1;//回文半径减一就是回文长度 
}

int main()
{
	string str="1232141267997621";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<Manacher(str,length)<<endl; 
}

3.用递归实现,复杂度渣到极限O(n*2^n)

/*用递归实现求最长回文长度,复杂度O(n*2^n)*/
#include <iostream>
using namespace std;
bool is_hw(char *start,char *end)
{
	while(start<end)
		if(*start!=*end) return false;
		else ++start,--end;
	return true;
} 
int urec_(char *start,char *end) 
{
	if(start==end) return 1;
	else if(start<end)
	{
		if(is_hw(start,end)) return end-start+1;
		else return max(rec_(start+1,end),rec_(start,end-1));
	} 
}

int main()
{
	string str="123214126798797621";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<rec_(&str[0],&str[0]+length)<<endl; 
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

求字符串中最大的回文长度

啊,接着上一篇判断字符串是否回文的问题,这一篇来解决另一个问题,求一个字符串当中最长的回文长度。 思路呢,因为考虑到一个任意的字符串,用中心向两边扩散的方法来判断回文是靠谱的。即,如果一段字符串是回...
  • u010159842
  • u010159842
  • 2015年05月27日 17:05
  • 1479

java实现求最大回文长度

以每个位置为中心,向两端扩展,计算以每个位置为中心的最大的palindrome。 时间O(n^2),空间O(1);   public class Solution {     public s...
  • zhang434
  • zhang434
  • 2014年04月15日 22:51
  • 1316

求字符串的最大回文子串

求字符串s1的最大回文子串,首先构造一个s1的反转字符串s2,然后求s1、s2的最大公共子串,求出的最大公共子串就是s1的最大回文子串...
  • xiaojimanman
  • xiaojimanman
  • 2015年10月08日 16:59
  • 2886

一个字符串的最大回文前缀长度(搜狗2017秋招真题)

一个字符串的最大回文前缀长度(搜狗2017秋招真题) 题目描述 求一个字符串的最大回文前缀长度。回文是指正反方向读起来都一样的字符串,比如“abcdcba”就是一个回文。 ...
  • ddd_1206
  • ddd_1206
  • 2017年08月31日 16:10
  • 647

算法导论-第15章-动态规划-15-2 最长回文子序列(LPS)

问题描述 回文序列(Palindromic sequence, Palindrome)是指正向遍历和反向遍历完全相同的序列,例如字符串“AAAAA”显然是一个回文序列,又如字符串“ABC@CBA”也是...
  • u012243115
  • u012243115
  • 2014年11月11日 14:11
  • 3110

求已知字符串的最大回文字符串长度,并输出该字符串

求已知字符串的最大回文字符串长度,并输出该字符串(不考虑数字) 输入示例:      Madam,I'm Adam. 输出示例:      Madam,I'm Adam. 题目分析: 输入分析:C...
  • qq_26010491
  • qq_26010491
  • 2015年10月24日 15:56
  • 1009

提取最长回文子串的java实现

题目描述 给定一个字符串,找出该字符串的最长回文子串。回文字符串指的就是从左右两边看都一样的字符串,如aba,cddc都是回文字符串。字符串abbacdc存在的回文子串有abba和cdc,因此它的最...
  • hanleijun
  • hanleijun
  • 2014年05月09日 22:02
  • 3617

字符串最大回文子串的查找java实现

java实现字符串回文判断,求字符串最长子回文串
  • qq1004642027
  • qq1004642027
  • 2015年01月07日 20:08
  • 2866

Java给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

//给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. //回文就是正反读都是一样的字符串,如aba, abba等 import java.util.Scanner...
  • lxj9312
  • lxj9312
  • 2016年08月18日 17:07
  • 765

求两个字符串中的最长公共子串的长度

利用二位矩阵对角线解决 #include #include using namespace std; int getLCSLength(string str1, string str2){ in...
  • yangshuangtao
  • yangshuangtao
  • 2015年09月29日 14:10
  • 1317
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:求字符串中的回文最大长度
举报原因:
原因补充:

(最多只允许输入30个字)