(1)暴力法:取到所有的子字符串,并判断是否为回文字符串,是的话就记录它的长度为临时最大长度,并将其保存到list中,继续向后遍历,如果有长度和它相等或者大于它的新回文子串,那么就将list清空,存入新子串,并记录长度为临时最大长度,直至完成;
class Solution {
public String longestPalindrome(String s) {
List<String> list = new ArrayList<>();
int max = 0;
if (s == null || s.length() < 1) return "";
for (int i = 0;i < s.length();i ++) {
for (int j = i + 1; j <= s.length(); j ++) {
String sub = s.substring(i,j);
if (checkString(sub)) {
if (sub.length() >= max) {
list.clear();
list.add(sub);
max = sub.length();
}
/** else if (sub.length() == max) {
list.add(sub);
}**/
}
}
}
return list.get(0);
}
public boolean checkString(String s) {
StringBuffer buffer = new StringBuffer();
buffer.append(s);
if (s.equals(buffer.reverse().toString())) {
return true;
}
return false;
}
}
该方法的时间复杂度是O(n~3),提交会提示时间超出限制,需要改进;
(2)中心扩展法:其实所有的回文子串都是垂直轴对称图形,我们只需要找到那个中心轴对应的点,然后向两边扩展,共有2*length()- 1个中心,回文字符串的中心,向两边扩展后的字符是一样的,根据这个准则筛选,因为奇偶不同分开即可,并记录长度,直到遍历完成,找到长度最长的就OK,这样时间复杂度就是O(n~2),比暴力法要好一些。
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.length() == 0)
return "";
int start = 0, end = 0;
for(int i = 0; i < s.length(); i ++) {
//中心在元素上
int len1 = explanString(s,i,i);
//中心在两元素之间
int len2 = explanString(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);
}
public int explanString(String s,int left,int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left --;
right ++;
}
//因为此时right已经++,left已经--,长度在索引差的基础上+1;
return right - left -1;
}
}