同样采用中心扩展法,思路如下图:
首先,填充字符串变成数组,然后以某个基准元素,求得它的最大回文子串,记录基准元素的索引pointI,以及回文长度maxLength也就是填充后的字符数组,求得最大回文子串的step步长。
通过pointI和maxLength就可以在填充后的字符数组里找到这个字串了。
/**
* 返回一个字符串最长回文字串部分
* @param s
* @return
*/
public static String longestPalindrome(String s) {
//先填充特殊字符,让字符数组长度变成奇数
StringBuilder sb = new StringBuilder();
String specialChar = "%";
sb.append(specialChar);
for(char a : s.toCharArray()){
sb.append(a);
sb.append(specialChar);
}
//填充完成后,开始遍历字符数组每个元素,找到以该元素为中心的最大回文字串的长度,并记住索引
char[] resultCharArr = sb.toString().toCharArray();
System.out.println(resultCharArr);
int maxLength = 0;
int pointI = 0;//记录获取较大回文串时候,基准元素的索引i
for (int i = 0; i < resultCharArr.length; i++) {
int tmpLength = 0;//记录以当前元素为基准的回文子串长度
for (int j = 0; j <=i && j<resultCharArr.length-i ; j++) {//以基准为中心,步长step=1向外扩张,注意这里j必须《=i,否则长度为1的回文字符就被忽略出错
if(resultCharArr[i-j] == resultCharArr[i+j]){//如果周边对称两点相等,回文长度加1
tmpLength++;
}else {
break;//如果周边对称两点不相等,这以该点为基准的最长回文已获得
}
}
if(tmpLength>maxLength){//如果当前基点获得了较大的子串回文
pointI = i;
maxLength = tmpLength-1;
}
}
System.out.println(pointI+" "+maxLength);
//遍历完成后,就获得了基准索引pointI,以及周边步长point范围内的回文,需除掉特殊字符
StringBuilder r = new StringBuilder();
for(int i=pointI-maxLength;i<=pointI+maxLength;i++){
if(!String.valueOf(resultCharArr[i]).equals(specialChar)){
r.append(resultCharArr[i]);
}
}
return r.toString();
}