题目描述:
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
package niu;
import java.util.*;
public class niuKe010 {
/*对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
*给定字符串A以及它的长度n,请返回最长回文子串的长度。
*/
public int getLongestPalindrome1(String A, int n) {
/*这个题目用到了动态规划的思想具体
*注意字符串的遍历顺序一定是从后向前的,因为这样才能解决之前没有计算而直接出答案的问题。
*这里的dp数组比较难想,是应该存储所经过的子字符串是否是回文数
*/
// write code here
char[] aa =A.toCharArray();
int max=1;
boolean[][] dp = new boolean[n][n];
for(int i=0;i<n;i++){
dp[i][i] = true;
}
for(int i=1;i<n;i++)//i指向的是字符的最后一位
for(int j=i-1;j>=0;j--){//j指向的是字符的前部。
/*判断相邻的字符串是否相等*/
if(i-j==1){//当两个指针靠近时,直接判断
dp[j][i]=(aa[i]==aa[j]);
if(max<i-j+1)
max = i-j+1;
}
else{
/*若两边相等在判断中间的是否相等*/
if(dp[j+1][i-1]&&aa[i]==aa[j]){
dp[j][i]=true;
if(max<i-j+1)
max = i-j+1;
}
else
dp[j][i]=false;
}
}
return max;
}
public int getLongestPalindrome2(String A, int n) {
int maxLen = 0;
//暴力解法,判断子串是不是回文子串
for(int i = 0; i < n; i++){
for(int j = i+1; j <= n; j++){
String now = A.substring(i,j);
if(isPalindrome(now) && now.length() > maxLen){
maxLen = now.length();
}
}
}
return maxLen;
}
//判断子串是不是回文子串
public boolean isPalindrome(String s){
int l = s.length();
for(int i = 0; i < l/2; i++){
if(s.charAt(i) != s.charAt(l-i-1))
return false;
}
return true;
}
public int getLongestPalindrome3(String A, int n) {
// write code here
char[] ch = A.toCharArray();
int res = 0;
for(int i = 0; i < n; i++){
int l = i, r = i, sameR = i;
//定位左右两边,避免abba和aba
//判断是abba还是aba
while(l - 1 >= 0 && ch[l - 1] == ch[i]) l--;
while(r + 1 < n && ch[r + 1] == ch[i]) r++;
sameR = r;//记录回文数的最末尾标号
while(l - 1 >= 0 && r + 1 < n && ch[l - 1] == ch[r + 1]){
l--;
r++;
}
res = Math.max(res, r - l + 1);
//优化
i = sameR;//直接从回文数后一位开始
}
return res;
}
public static void main(String[] args) {
Scanner sc1 =new Scanner(System.in);
String A = sc1.nextLine();
Scanner sc2 =new Scanner(System.in);
int n = sc2.nextInt();
niuKe010 p = new niuKe010();
int res = p.getLongestPalindrome1(A,n);
System.out.println(res);
}
}