最长回文串的四种解法
2017-10-10 16:47
369 查看
1.暴力求回文串
2.动态规划求回文串
3.中心扩展法求回文串
4.Manacher算法详解
第一种:
第二种:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MOD 1000000007
#define MX 5005
int n;
int len;
char temp[MX];
char str[MX*2];
int p[MX*2];
int dp[MX*2];
void Init()
{
len = 0;
str[len++]='@';
str[len++]='#';
n = strlen(temp);
for (int i=0;i<n;i++)
{
str[len++]=temp[i];
str[len++]='#';
}
memset(p,0,sizeof(p));
}
void Manacher()
{
Init();
int mx = 0, id =0;
for (int i=1;i<len;i++)
{
p[i] = mx>i ? min(p[2*id-i],mx-i):1;
while (str[i+p[i]]==str[i-p[i]]) p[i]++;
if (i+p[i]>mx)
{
mx = i+p[i];
id = i;
}
}
}
string findLongestPalindrome(string &s) { int length=s.size();//字符串长度 int maxlength=0;//最长回文字符串长度 int start;//最长回文字符串起始地址 for(int i=0;i<length;i++)//起始地址 for(int j=i+1;j<length;j++)//结束地址 { int tmp1,tmp2; for(tmp1=i,tmp2=j;tmp1<tmp2;tmp1++,tmp2--)//判断是不是回文 { if(s.at(tmp1)!=s.at(tmp2)) break; } if(tmp1>=tmp2&&j-i>maxlength) { maxlength=j-i+1; start=i; } } if(maxlength>0) return s.substr(start,maxlength);//求子串 return NULL; }
2.动态规划求回文串
string findLongestPalindrome(string &s) { const int length=s.size(); int maxlength=0; int start; bool P[50][50]={false}; for(int i=0;i<length;i++)//初始化准备 { P[i][i]=true; if(i<length-1&&s.at(i)==s.at(i+1)) { P[i][i+1]=true; start=i; maxlength=2; } } for(int len=3;len<length;len++)//子串长度 for(int i=0;i<=length-len;i++)//子串起始地址 { int j=i+len-1;//子串结束地址 if(P[i+1][j-1]&&s.at(i)==s.at(j)) { P[i][j]=true; maxlength=len; start=i; } } if(maxlength>=2) return s.substr(start,maxlength); return NULL; }
3.中心扩展法求回文串
string findLongestPalindrome(string &s) { const int length=s.size(); if(length == 1)return s; if(length == 0)return NULL; int maxlength=0; int start; for(int i=0;i<length;i++)//长度为奇数 { 4000 int j=i-1,k=i+1; while(j>=0&&k<length&&s.at(j)==s.at(k)) { if(k-j+1>maxlength) { maxlength=k-j+1; start=j; } j--; k++; } } for(int i=0;i<length;i++)//长度为偶数 { int j=i,k=i+1; while(j>=0&&k<length&&s.at(j)==s.at(k)) { if(k-j+1>maxlength) { maxlength=k-j+1; start=j; } j--; k++; } } if(maxlength>0) return s.substr(start,maxlength); return NULL; }
4.Manacher算法详解
第一种:
#define min(x, y) ((x)<(y)?(x):(y)) #define max(x, y) ((x)<(y)?(y):(x)) string findLongestPalindrome3(string s) { int length=s.size(); for(int i=0,k=1;i<length-1;i++)//给字符串添加 # { s.insert(k,"#"); k=k+2; } length=length*2-1;//添加#后字符串长度 int *rad=new int[length](); rad[0]=0; for(int i=1,j=1,k;i<length;i=i+k) { while(i-j>=0&&i+j<length&&s.at(i-j)==s.at(i+j)) j++; rad[i]=j-1; for(k=1;k<=rad[i]&&rad[i-k]!=rad[i]-k;k++)//镜像,遇到rad[i-k]=rad[i]-k停止,这时不用从j=1开始比较 rad[i+k]=min(rad[i-k],rad[i]-k); j=max(j-k,0);//更新j } int max=0; int center; for(int i=0;i<length;i++) { if(rad[i]>max) { max=rad[i]; center=i; } } return s.substr(center-max,2*max+1); }
第二种:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MOD 1000000007
#define MX 5005
int n;
int len;
char temp[MX];
char str[MX*2];
int p[MX*2];
int dp[MX*2];
void Init()
{
len = 0;
str[len++]='@';
str[len++]='#';
n = strlen(temp);
for (int i=0;i<n;i++)
{
str[len++]=temp[i];
str[len++]='#';
}
memset(p,0,sizeof(p));
}
void Manacher()
{
Init();
int mx = 0, id =0;
for (int i=1;i<len;i++)
{
p[i] = mx>i ? min(p[2*id-i],mx-i):1;
while (str[i+p[i]]==str[i-p[i]]) p[i]++;
if (i+p[i]>mx)
{
mx = i+p[i];
id = i;
}
}
}
相关文章推荐
- 求字符串的最长回文串的O(n)解法
- 最长回文串的不同解法。
- poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)
- JAVA动态规划(二)--最长公共子序列问题(LCS_subSequence)的三种解法与最长公共子字符串(LCS_subString)的两种解法与最长回文串(LongestPalindrome)
- 最长回文串的解法
- 最长回文串的解法---Manacher算法
- Ural1297Palindrome最长回文串.manacher解法
- 最长公共子串问题的后缀数组解法
- 【bzoj2565】最长双回文串
- BZOJ2565 最长双回文串
- 猴子选大王的四种VB解法
- BZOJ 2565 最长双回文串
- 最长上升子序列 O(nlogn)解法 (转)
- hdu3068 最长回文串
- HDU-1004-提供四种解法--map解法/自己写二叉排序树/hash/字典树
- HDU 3068 最长回文串
- 最长回文串
- 最常回文串和最长回文序列
- 最长公共上升子序列的DP解法及其优化
- 求最长回文串-从动态规划到"马拉车"之路(下)