java-NC17 最长回文子串
import java.util.*;
/**
* NC17 最长回文子串
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param A string字符串
* @return int整型
*/
public int getLongestPalindrome (String A) {
// return solution1(A);
// return solution2(A);
// return solution3(A);
return solution4(A);
}
/**
* 滑动窗口
* @param A
* @return
*/
private int solution1(String A){
int len = A.length();
for(int gap = len; gap > 0; gap--){
for(int i = 0; i+gap <= len; i++){
if(isPalindrome(A.substring(i, i+gap))){
return gap;
}
}
}
return 0;
}
/**
* 是否回文串
* @param sub
* @return
*/
private boolean isPalindrome(String sub){
for(int i=0,j=sub.length()-1; i<j; i++,j--){
if(sub.charAt(i) != sub.charAt(j)){
return false;
}
}
return true;
}
/**
* 是否回文串
* @param sub
* @return
*/
private boolean checkPalindrome(String sub){
return sub.equals(new StringBuffer(sub).reverse().toString());
}
/**
* 动态规划
*
* dp[i][j]表示子串[i,j](下标从0开始)是否为回文串(dp[i][j]=0: 非回文串 , dp[i][j]>0: 为回文串)
*
* { = 0, 子串[i,j]非回文串
* dp[i][j] {
* { > 0, 子串[i,j]为回文串 且长度为该值
* @param A
* @return
*/
private int solution2(String A){
char[] chars = A.toCharArray();
int len = chars.length;
int result = 1;
int[][] dp = new int[len][len];
for(int i = 0; i < len; i++){
dp[i][i] = 1;
}
for(int i = 0; i+1 < len; i++){
if(chars[i] == chars[i+1]){
dp[i][i+1] = 2;
result = 2;
}
}
for(int gap = 2; gap < len; gap++){
for(int i = 0; i+gap < len; i++){
// 左右两边字符相同 且 之间子串为回文串
if(chars[i]==chars[i+gap] && dp[i+1][i+gap-1]>0){
// 回文串 长度+2
dp[i][i+gap] = dp[i+1][i+gap-1] + 2;
}else{
// 非回文串
dp[i][i+gap] = 0;
}
result = Math.max(result, dp[i][i+gap]);
}
}
return result;
}
/**
* 贪心: 中心扩展法
* @param A
* @return
*/
private int solution3(String A){
int result = 1;
for(int i = 0; i+1 < A.length(); i++){
result = Math.max(result, Math.max(spread(A,i,i), spread(A,i,i+1)));
}
return result;
}
/**
* 中心扩展法: 分别向左右两边扩展
* @param A
* @param left
* @param right
* @return
*/
private int spread(String A, int left, int right){
while(0<=left && right<A.length() && A.charAt(left)==A.charAt(right)){
left--;
right++;
}
return right-left-1;
}
/**
* Manacher算法
* @return
*/
private int solution4(String A){
char[] mChars = manacher(A);
int mCharsLen = mChars.length;
// 回文半径
int[] pRadius = new int[mCharsLen];
int index = -1;
// 之前已经遍历字符各回文半径最右侧再往右一位 -> 最右即将到达的位置
int pRight = -1;
int max = 1;
for(int i = 0; i < mCharsLen; i++){
pRadius[i] = pRight>i ? Math.min(pRadius[2*index-i], pRight-i) : 1;
while(0<=i-pRadius[i] && i+pRadius[i]<mCharsLen){
if(mChars[i-pRadius[i]] == mChars[i+pRadius[i]]){
pRadius[i]++;
}else{
break;
}
}
// pRight
if(i+pRadius[i] > pRight){
pRight = i+pRadius[i];
index = i;
}
// 回文串长度 pRadius[i]-1
max = Math.max(max, pRadius[i]-1);
}
return max;
}
/**
* 字符串初始化处理: 奇回文串 和 偶回文串 方便统一处理
*
* bcbaa -> #b#c#b#a#a#
* ba -> #b#a#
*
* @param str
* @return
*/
private char[] manacher(String str){
char[] chars = str.toCharArray();
char[] result = new char[str.length()*2+1];
int index = 0;
for(int i = 0; i < result.length; i++){
result[i] = (i&1)==0 ? '#' : chars[index++];
}
return result;
}
}