题目:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
想到回文串,应该联想到双指针。一头一尾的指针不停的移动比对,当出现了首尾的字符不同时,则记录此时回文串的长度。
由于此题是找最长的回文串,所以我们可以遍历每个字符,以当前遍历的字符为中心,用两个指针向远离的方向一头一尾移动。同时,在遍历的同时更新最长的回文串。
很遗憾,在提交测试后,这样的做法没有通过。
主要是因为s的长度为奇数和偶数的区别。
故针对奇数和偶数的情况分别处理,这样就不会漏处理相关场景了。
首先,写一个返回以某个中点向两边扩散的方法。
// left与right是两个指针,起始状态left与right两个指针是靠拢的(传值控制)
public String palindrome(String s, int left , int right) {
// 从中心往两头走
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
// 向两边走
left--;
right++;
}
// 返回此时最长的回文串
return s.substring(left + 1, right);
}
然后,以为每个字符为中心来计算回文串。
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return s;
}
String res = "";
for (int i = 0; i < s.length(); i++) {
// 每次以i为中心向外扩散
// 处理s的长度为奇数的情况
String s1 = palindrome(s, i, i);
// 处理s的长度为偶数的情况, 这个处理很重要。(例如s为abba的情况,s1计算的结果是0,而实际情况是4。s2的计算补齐了这个场景)
String s2 = palindrome(s, i, i + 1);
// 再遍历的过程中更新长度
res = s1.length() >= res.length() ? s1 : res;
res = s2.length() >= res.length() ? s2 : res;
}
return res;
}
此题,主要是要联想到双指针以及注意字符串奇偶长度的处理。