题目描述:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 长度最长为1000。
示例:
输入: "babad" 输出: "bab" 注意: "aba"也是有效答案
示例:
输入: "cbbd" 输出: "bb"
方法1:暴力破解,遍历所有的子串,求子串的复杂度是O(n2),判断回文是O(n),所以整体时间复杂度是O(n3)。在Leetcode超时,所以不能使用。
private int start = 0; // 记录回文子串的起始位置
private int maxLen = 0; // 记录回文子串的最长长度
/**
* 暴力解法,遍历每一个子串,然后判断是否是回文
* @param s
* @return
*/
public String longestPalindrome1(String s){
int len = s.length();
int i = 0, j = 0;
for (; i < len; i++){
for (j = 0; j < len && i+j<len; j++){
String temp = s.substring(i, i+j+1);
if (isPalindrome(temp)){
if (maxLen < temp.length()){
maxLen = temp.length();
start = i;
}
}
}
}
String r = s.substring(start, start+maxLen);
return r;
}
public boolean isPalindrome(String s){
for (int i = 0, len = s.length(), j = len-1; i <= j; i++, j--){
if (s.charAt(i) != s.charAt(j)){
return false;
}
}
return true;
}
方法2:中心法,因为回文都是中心对称的,所以由中心向两侧进行延伸,然后判断是否是回文。整体时间复杂度是O(n2)。在leetcode可以通过。因为回文串的长度奇偶不定,所以当时偶数时,例如s="bb";那么需要extendPalindrome(s, i, i+1)开始延伸;如果是奇数,例如s="bab",则是从正中间开始延,即extendPalindrome(s, i, i);
private int start = 0; // 记录回文子串的起始位
private int maxLen = 0; // 记录回文子串的最长长度
/**
* 中心法,向两端扩散
* @param s
* @return
*/
public String longestPalindrome(String s) {
start = 0;
maxLen = 0;
for (int i = 0, len = s.length(); i < len; i++){
extendPalindrome(s, i, i);
extendPalindrome(s, i, i+1);
}
String r = s.substring(start, start+maxLen);
return r;
}
public void extendPalindrome(String s, int l, int r){
for (int len = s.length(); l >= 0 && r < len; l--, r++){
if (s.charAt(l) == s.charAt(r)){
int k = r - l + 1;
if (maxLen < k){
maxLen = k; //记录最新的字符串长度
start = l;
}
}else{
break;
}
}
}
还有简单方法,等我掌握好了,测试通过之后,再来更新!!!