第一种:暴力枚举法
class Solution {
public String longestPalindrome(String s) {
String result = null;
int max = 0;
int i = 0;
while(i < s.length()){
for(int j = i; j < s.length(); j++) {
if(j - i + 1 < max) {
continue;
}//长度小于目前最长回文,跳过
String str = s.substring(i,j+1);
if(isP(str) && j - i + 1 > max){
max = j - i + 1;
result = str;
}
}
i++;
}
return result;
}
public boolean isP(String s) {
int i = 0, j = s.length()-1;
while(i < j) {
if(s.charAt(i) != s.charAt(j)){
return false;
}
i++;
j--;
}
return true;
}
}
第二种:中心扩展算法
class Solution {
public String longestPalindrome(String s) {
int start = 0, end = 0;
for(int i =0; i < s.length(); i++){
int len1 = longP(s, i, i);//以单个字符为中心的回文
int len2 = longP(s, i, i+1);//以两个字符为中心的回文
int len = Math.max(len1, len2);//取两者最大值
if(len > end - start + 1) {//当前回文长度最大时,进行更新
start = i - (len - 1)/2;
end = i + len/2;
}
}
return s.substring(start, end + 1);
}
public int longP(String s, int l, int r) {
while(l >= 0 && r < s.length()) {//向左右扩散,直到不是回文为止
if(s.charAt(l) == s.charAt(r)) {
l--;
r++;
}else{
break;
}
}
return r - l - 1;//返回其长度
}
}
第三种:动态规划
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
int start = 0, end = 0;
if(n < 2) {//单个字符
return s;
}
boolean[][] dp = new boolean[n][n];
for(int i = 0; i < n; i++) {//所有单个字符都为true
dp[i][i] = true;
}
//状态方程
for(int j = 1; j < n; j++) {
for(int i = 0; i < j; i++) {
if(s.charAt(i) == s.charAt(j)) {
if(j - i + 1 <= 3) {//长度小于等于3 必然是回文
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];//由子串决定
}
}else{
dp[i][j] = false;
}
if(dp[i][j] && j - i > end - start){//更新
start = i;
end = j;
}
}
}
return s.substring(start, end + 1);
}
}