您的位置:首页 > 其它

leetCode—Longest Palindromic Substring

2015-08-07 22:04 405 查看
Description:Given a string S,
find the longest palindromic substring in S. You may assume that the maximum length of S is
1000, and there exists one unique longest palindromic substring.

问题描述:给出一个字符串,求出这个字符串的最大回文子字符串。

解法一:看到这个问题,我们首先很容易想出时间复杂度是O(n^2),空间复杂度为O(n^2)的动态规划方法



代码如下:

public String longestPalindrome(String s) {
if(s==null||s.length()==0)
return null;
int n=s.length();
int longestBegin=0;
int maxLen=1;
boolean[][] table=new boolean

;

for(int i=0;i<n;i++){
table[i][i]=true;
}

for(int i=0;i<n-1;i++){
if(s.charAt(i)==s.charAt(i+1)){
table[i][i+1]=true;
longestBegin =i;
maxLen=2;
}
}

for(int i=n-3;i>=0;i--){
for(int j=i+1;j<n;j++){
if(s.charAt(i)==s.charAt(j)&&table[i+1][j-1]){
table[i][j]=true;
if(maxLen<j-i+1){
longestBegin=i;
maxLen=j-i+1;
}
}
}
}

return s.substring(longestBegin,longestBegin+maxLen);
}



解法二:
那么,是不是有时间复杂度和空间复杂度的都是线性的解决方法了,答案是肯定的,那就是使用Manacher’s Algorithm,(我翻译为马努切尔算法)。算法的思想可以查看这篇博客(Manacher's
ALGORITHM)和Longest Palindromic Substring Part II,这个算法我从阅读思想到实现,我花了半天的时间,一开始根本看不懂,准备放弃,最后坚持看下去了,当自己写的代码通过的时候,心里还是很开心的。废话不多说了,直接给出我写的代码:

public static  String longestPalindrome(String s) {
if(s==null||s.length()==0)
return null;

int[] arr=getP(s);
int max=arr[0];
int center=0;
for(int i=1;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
center=i;
}
}
String res=null;
int centerIndex=0;
//这里面需要考虑这两种情况
if(center%2==0){
centerIndex=(center-2)/2;
res=s.substring(centerIndex-(max-2)/2,centerIndex+(max-2)/2+1);
}
else{
centerIndex=(center-1)/2;

res=s.substring(centerIndex-(max-1)/2, centerIndex+(max-1)/2);
}
return res;

}

/**
* S $#1#2#2#1#2#3#2#1#^
* P 0121252141216121210
*这个函数就是求这里面的P数组
*(p.s. 可以看出,P[i]-1正好是原字符串中回文串的总长度)
* */
public static int[] getP(String s){
String str=preprocess(s);
int[] p=new int[str.length()];
int mx=0;
int id=0;
for(int i=1;i<str.length()-1;i++){
if(mx>i){
p[i]=Math.min(p[2*id-i], mx-i);
}
else
p[i]=1;

while(str.charAt(i+p[i])==str.charAt(i-p[i]))
{	p[i]++;

}

if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
}

return p;
}

/**
*处理字符串,把字符串形如“12212321”转化成“$#1#2#2#1#2#3#2#1#^”
*(1)在头尾加$和^字符串可以使我们不用考虑越界问题
*(2)在中间加#字符串是为了使字符串的长度为奇数,这样就不用分奇偶两种
*情况去考虑了,处理起来更加方便
**/

private static String preprocess(String str){
int length=str.length();
char[] ch=new char[2*length+3];
ch[0]='$';
for(int i=0;i<str.length();i++){
ch[2*i+1]='#';
ch[2*i+2]=str.charAt(i);
}
ch[2*length+1]='#';
ch[2*length+2]='^';

return String.valueOf(ch);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: