题目:
给你一个字符串 s,找到 s 中最长的回文子串。
解题思路
中心扩散法:从左向右遍历,以每个元素为一个中心,利用“回文串”中心对称的特点,左右扩散,看最多能扩散多远。
1.先看当前元素是否与其相邻的右侧元素相同,若相同则 right 指针向右移动一位,回文串长度加 1
2.再看当前元素是否与其相邻的左侧元素相同,若相同则 left 指针向左移动一位,回文串长度加 1
3.最后看当前 left 指针和 right 指针指向的元素是否相同,若相同则 left 指针左移以及 right 指针右移,并且回文串长度加 2。
4.若没有满足以上三个条件的元素时,则判断当前得到的回文串长度是否比之前的要长。若比之前长,则记录新的回文串的长度以及该回文串的开始和结尾时的下标(此时,需要将 left 指针右移一位以及 right 指针左移一位。因为,当进入该判断时,此时的两个指针所指向的元素并不满足回文串的条件,所以应将两指针均回移一位)。
5.将回文串长度重新设置为 1,继续下一个元素的遍历直到结束。
代码:
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
int left = 0, right = 0, Length = 1, maxLength = 0;
int maxBegin = 0, maxEnd = 0;
for (int i=0;i<n;i++) {
left = i - 1;
right = i + 1;
//看当前元素是否与其相邻的右侧元素相同
while (right < n && s.charAt(i) == s.charAt(right)) {
right++;
Length++;
}
//看当前元素是否与其相邻的左侧元素相同(判断完右侧可以再判断左侧)
while (left >= 0 && s.charAt(left) == s.charAt(i)) {
left--;
Length++;
}
while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {
left--;
right++;
Length += 2;
}
if (Length > maxLength) {
maxBegin = left + 1;//此时left指针指向的元素并不满足要求,应回移一位
maxEnd = right - 1;//right指针指向的元素不满足要求,应回移一位
maxLength = Length;
}
Length = 1;
}
//substring方法返回从指定的maxBegin处开始,一直到索引maxEnd - 1处的字符,所以 + 1
return s.substring(maxBegin, maxEnd + 1);
}
}