【题目】
给你一个字符串
s
,找到s
中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
初步分析:需要返回最长的回文串,则需要拿到最长回文串的位置下标,从输入字串中截取
【解题说明】
中心扩散法:以某一个位置为中心,向周围扩散,直到满足条件或到达边界。
思路一:
遍历字串中的每一个字符,寻找以这个字符为中心的最长回文串:
1、从当前字符位置向左寻找和当前字符相同的字符,直到没有相同的为止;
2、从当前字符位置向右寻找和当前字符相同的字符,直到没有相同的为止;
3、从当前位置向左和向右同时寻找左右相同的字符,直到没有相同的为止;
使用变量maxLength记录最长回文串的长度,变量start记录回文串的开始位置,left、right、len分别表示当前循环内左侧字符下标、右侧字符下标、回文串长度,如果len > maxLength,更新maxLength,同时更新start为left。
public String longestPalindrome(String s) {
if (s == null || s.trim().equals("")) {
return "";
}
int maxLength = 0;
int start = 0;
int left = 0;
int right = 0;
char[] charArray = s.toCharArray();
for (int i = 0; i < charArray.length; i++) {
left = i - 1;
right = i + 1;
int len = 1;
// 寻找当前字符左侧与之相同的字符,如果存在,则left向左移动,回文串长度len+1
while (left >= 0 && charArray[left] == charArray[i]) {
left--;
len++;
}
// 寻找当前字符右侧与之相同的字符,如果存在,则right向右移动,回文串长度len+1
while (right < charArray.length && charArray[right] == charArray[i]) {
right++;
len++;
}
// 寻找当前字符左右两侧相同的字符,如果存在,则right向右移动,left向左移动,回文串长度len+2
while (left >= 0 && right < charArray.length && charArray[left] == charArray[right]) {
left--;
right++;
len = len + 2;
}
// 更新最长回文串长度和回文串开始下标
if (maxLength < len) {
maxLength = len;
start = left;
}
if (maxLength == charArray.length) {
break;
}
}
return s.substring(start + 1, start + maxLength + 1);
}
思路二:
回文串长度以奇数和偶数区分,奇数串中心为一个字符,偶数串中心为两个字符,分别以一个字符、两个字符为中心,寻找最长回文串
private int maxLength = 0;
private int left = 0;
public String longestPalindrome(String s) {
if (s == null || s.trim().equals("")) {
return "";
}
char[] charArray = s.toCharArray();
for (int i = 0; i < charArray.length; i++) {
getResult(charArray, i, i, charArray.length);
getResult(charArray, i, i + 1, charArray.length);
}
System.out.println(s.substring(left, left + maxLength));
return s.substring(left, left + maxLength);
}
public void getResult(char[] charArray, int i, int j, int length) {
while (i >= 0 && j < length && charArray[i] == charArray[j]) {
if (j - i + 1 > maxLength) {
maxLength = j - i + 1;
left = i;
}
i--;
j++;
}
}