最长回文子串(longest Palindrome)
①longest common substring
将原字符串str1整个转置(reverse)得到str2,对str2的所有子字符串substr2,检查str1是否包含substr2,如果包含,这里要特别注意检查,substr2是否是一个回文串,例如str1=“bacac”,则str2=“cacab”,此时substr2=“cac”,正确,但是若str1=“eeecdfeee”,则str2="eeefdceee",此时substr2=“eee”,错误,所以对于substr2是否是回文串的检查是非常必要的。
要点:利用动态规划的方法找出原字符串和它转置后得到的字符串的“最长公共字符串”,同时要保证该“最长公共字符串”是一个回文串
以下是我的具体实现,leetcode上面说时间复杂度为O(n^2,然后我写了一下,一直是超时错误,不知道从哪里改进了〒_〒)
public String longestPalindrome(String s) {
StringBuffer str1 = new StringBuffer();
//整个转置之后得到的字符串
StringBuffer str2 = new StringBuffer(s);
str2.reverse();
int[][] c = new int[2][s.length()+1];
int maxI=0;//当前最长公共子字符串的位置
int length=0;//最长公共子字符串的长度
for(int i = 1; i < s.length()+1; i++)
{
for(int j = 1; j < str2.length()+1; j++)
{
if(s.charAt(i-1)==str2.charAt(j-1))
c[1][j]=c[0][j-1]+1;
else
c[1][j]=0;
if(c[1][j]>length){
if(s.substring(i-c[1][j],i).equals(str2.substring(s.length()-i,s.length()-i+c[1][j])))
{
length=c[1][j];
maxI=i;
}
}
}
for(int k=0;k<str2.length()+1;k++)
{
c[0][k]=c[1][k];
c[1][k]=0;
}
}
return s.substring(maxI-length, maxI).toString();
②暴力破解法(穷举所有的子串,并判断其是否是回文串),时间复杂度O(n^3),超时
③动态规划法,时间复杂度O(n^2)
int length=s.length();
int maxlength=1;
int start =0;
boolean[][]P = new boolean[s.length()][s.length()];
for(int i=0;i<length;i++)//初始化准备
{
P[i][i]=true; //对称点为一个字母
if(i<length-1&&s.charAt(i)==s.charAt(i+1))
{ //对称点为两个字母
P[i][i+1]=true;
start=i;
maxlength=2;