给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
1.暴力方法,三次循环
public boolean judge(char[] ch, int i, int j){
while(i < j){
if(ch[i] != ch[j]) return false;
i++;
j--;
}
return true;
}
public String longestPalindrome(String s) {
int len = s.length();
if(len == 0) return "";
char[] ch = s.toCharArray();
int maxL = -1, start = -1;
for(int i = 0; i < len; i++){
for(int j = i; j < len; j++){//注意应当包含单个字符
if(judge(ch, i, j)){
if(maxL < j - i+1){
maxL = j - i + 1;
start = i;
}
}
}
}
return s.substring(start, start +maxL);//注意真实index的下一位
}
2.扩展中心法,复杂度,n^2
具体讲解,参考L647. 回文子串
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
String ans = "";
for(int i = 0; i < 2*len - 1; i++){
int left = i / 2;
int right = left + i % 2;
while(left >= 0 && right < len && s.charAt(left) == s.charAt(right)){
String tmp =s.substring(left, right + 1);
if(tmp.length() > ans.length()){
ans = tmp;
}
left--;
right++;
}
}
return ans;
}
}
public String longestPalindrome(String s) {
String ans = "";
int length = s.length();
if(length == 0 || s == null) return ans;
int start = 0, maxL = 0;
for(int i = 0; i < length; i++){
int len1 = get(s, i, i);//以奇数为中心
int len2 = get(s, i, i+ 1);//以偶数为中心
int len = Math.max(len1, len2);
if(len > maxL){
if(len == len1) start = i - (len - 1)/2;
else start = i - (len - 2)/2;
maxL = len;
}
}
return s.substring(start,start + maxL);//注意不要忘记加上start
}
public int get(String s, int start, int end){
while(start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
//start++;
//end--;注意不是判断判断对称的
start--;
end++;
}
return end - start - 1;//因为此时两参数均已超出边界
}
3.动态规划法
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if (s == null || len < 2) return s;
boolean[][] dp = new boolean[len][len];
int start = 0, length = 1;//注意默认长度为1,不是0,对于只有两个字符,可以取第一个字母
for(int right = 1; right <len; right++){//能进来的默认都是超过2个字符
for(int left = 0; left < right; left++){//注意循环的写法,只有这样才能被下次计算利用到
if(s.charAt(left) == s.charAt(right) && (right - left < 3 || dp[left + 1][right - 1])){
dp[left][right] = true;
if(right - left + 1 > length){
length = right - left + 1;
start = left;
}
}
}
}
return s.substring(start, start + length);
}
}