题目梗概:
找出指定字符串中最长的回文子串。
解题思路:
最简单的方法应该是找出指定字符串的所有子串,从最长的子串开始判断是否是回文字符串,是则直接返回该子串,不是则继续对剩下的子串进行判断,直到找到回文字符串为止。
由于回文字符串的特点是“从中心到两端的字符一一对应”。主要有以下两种形式,对于单核回文,除中心字符外,左右两端的字符一一对应,如“aba”;对于双核回文,从中心开始到左右两端的字符都一一对应,如“abba”。因此,可以依据该特点对指定字符串进行遍历,找出符合情况的子串。
解题算法:
解法一
class Solution {
public String longestPalindrome(String s) {
if(s.length() <= 1) {
return s;
}
for(int i = s.length(); i > 0; i--) { // 子串长度
for(int j = 0; j <= s.length() - i; j++) { // 子串起始位置
String subString = s.substring(j, j + i); // 子串
boolean flag = true;
for(int z = 0; z < subString.length() / 2; z++) { // 判断是否是回文子串
if(subString.charAt(z) != subString.charAt(subString.length() - 1 - z)) {
flag = false;
break;
}
}
if(flag) {
return subString;
}
}
}
return "";
}
}
解法二
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.length() < 1) {
return "";
}
int start = 0;
int end = 0;
for(int i=0; i < s.length(); i++) {
int len1 = expandFromCenter(s, i, i); // 单核回文
int len2 = expandFromCenter(s, i, i+1); // 双核回文
int len = Math.max(len1, len2);
if(len > (end - start)) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
// 从中心向左右扩散
private int expandFromCenter(String s, int left, int right) {
while(left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
}