判断是不是palindromic是O(N)的,这个应该没有办法提高了,只能一个一个比较,如果是数字的话可以看reverse integer 那道题的O(1)的解法。
要记录最长回文,多种方法可供选择,先看naive的方法,用一个StringBuiler来存,每当发现一个更长的,就更新。之前提到的,substring在jdk7以上是O(N)的,所以这naive 的方法是O(N*N*N)
public String longestPalindrome(String s) {
if(s==null ||s.length()==1) return s;
StringBuilder ret = new StringBuilder("");
int i = 0;
int j = s.length()-1;
while(i<s.length() ) {
j=s.length()-1 ;
while( j > i){//substring包括下界不包括上界,j>i避免溢出,isPalindromic(substring)应该是O(N+N)的,如果理解错误欢迎指正
if(isPalindromic(s.substring(i, j)) && Math.abs(j+1-i)>ret.length()) ret = new StringBuilder(s.substring(i, j)) ;
j--;
}
i++;
}
return ret.toString();
}
public boolean isPalindromic(String s) {
//O(N)
int i = 0;
while(i < s.length()/2 && s.charAt(i) == s.charAt(s.length()-1-i) ) i++;
return i==s.length()/2 ? true:false;
}
下面是一个O(N*N)的方法,但是常数较大,内存只需要O(1)
public String longestPalindrome(String s) {
if(s==null ||s.length()==1) return s;
int i = 0;
String ret = new String();
while(i < s.length()) {
if(ret==null || ret.length() < helper(s, i).length()) ret = helper(s,i);
i++;
}
return ret;
}
public String helper(String s, int i){
//以一个字母对称
int left = i;
int right = i;
while(left>=0 && right < s.length() ) {
if(s.charAt(left)==s.charAt(right)) {
left--;
right++;
}
else break;
}
String odd = s.substring(left+1, right);
//以两个字母对称
left = i;
right = i+1;
while(left>=0 && right < s.length() ){
if(s.charAt(left)==s.charAt(right)) {
left--;
right++;
}
else break;
}
String even = s.substring(left+1, right);
return even.length() > odd.length()? even:odd;//返回较长的那个
}