题目描述:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
思想:
- 循环遍历字符串,以每一个子串为中心,向两侧扩散寻找回文串,也就是判断两侧字符是否相等;
- 首先判断剩余的字符数是否小于等于maxlen的一半,是的话说明当前maxlen已经是最大值了;
- 以每一个字符i为中心,设置左右指针left和right,移动指针即可;
- 要注意的是,需要向右遍历跳过重复项(针对奇偶回文串均适合);
PS:遇到回文问题,基本就是以每一个为中心,向两侧扩散即可,注意的是跳过重复项。
public class test1 {
public static String longestPalindrome(String s) {
//如果单个字符,直接返回
if(s.length() < 2) return s;
//start表示回文串其实位置,maxlen表示回文串长度
int start = 0, maxlen = 0;
//依次以i为中心,向两侧扩散
int i = 0;
while(i < s.length() - 1) {
//如果从i到串末尾之间的字符串个数<=maxlen/2,说明后续就算存在回文串也不是最大的
if(s.length()-1 - i + 1 <= maxlen/2) break;
//以当前字符i为中心,向两侧扩散,设置左右指针
int right = i, left = i;
//先向右跳过重复的字符,例如串abbba,初始left=right指向第一个b,
//向右跳过之后,left指向第一个b,right指向第三个b,然后再向两侧扩散
//这种处理方式,对于奇偶回文串均适用
while(right < s.length()-1 && s.charAt(right+1) == s.charAt(right)) right++;
//向两侧扩散
while(right < s.length()-1 && left > 0 && s.charAt(left-1) == s.charAt(right+1)) {
right++;
left--;
}
//更新maxlen
if(maxlen < right - left + 1) {
maxlen = right - left + 1;
start = left;
}
//更新i
i = right + 1;
}
//左侧(包含),右侧(不包含)
return s.substring(start, start + maxlen);
}
public static void main(String[] args) {
String result = longestPalindrome("cbbd");
System.out.println(result);
}
}