题目描述:给你一个字符串 s,找到 s 中最长的回文子串。
下面用中心扩展算法来解决这个问题,该算法的思路简单:遍历整个字符串,判断以单个字符或两个字符中间的夹缝为中心向两边拓展的字符串是否为回文串。判断的条件为左指针left和右指针right指向的字符是否相同。循环遍历比较回文串的长度,并记录最长回文子串的起始索引和结束索引。
java代码如下:
class Solution {
public String longestPalindrome(String s) {
// 若为null值或是空字符串,则返回""
if (s == null || s.length() == 0) {
return "";
}
int left = 0;
int right = 0;
// 遍历字符串
for (int i = 0; i < s.length(); i++) {
// 子回文串长度为奇数的情况
int len1 = expandAroundCenter(s, i, i);
// 子回文串长度为偶数的情况
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > right - left) {
// left = i = (len - 1) / 2中的len - 1是考虑到子回文串的长度是偶数的情况。
left = i - (len - 1) / 2;
right = i + len / 2;
}
}
// java中求子字符串为左闭右开
return s.substring(left, right + 1);
}
public int expandAroundCenter(String s, int left, int right) {
while(left >= 0 && right < s.length() && s.charAt(left) == s. charAt(right)) {
left --;
right ++;
}
return right - left + 1 - 2;
}
}
说两个值得注意的细节:
- 在expandAroundCenter函数中返回的值为right - left + 1 - 2。其中right - left + 1是指针指向的子字符串的长度,减二是因为要去掉首尾两个元素。
- 当子回文串的长度为奇数时,left和right指针从中间元素向两边偏移的长度相同。而当子回文串的长度为偶数时,left指针向左偏移的长度要比right向右偏移的长度小1。故if (len > right - left) {
left = i - (len - 1) / 2;
right = i + len / 2;
}
若有不正确的地方,忘请指正。