题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
思路
- 特殊情况,长度为1,直接返回
- 回文字符串分为两种类型,分类讨论
- 一种是以某个字符两边对称 a b c b a
- 另一种是两边对称(没有中心字符) a b b a
- 对于第一种,从下标1开始进行判断,从中心字符串向两边延伸,找最长
- 对于第二种,从下表0开始进行判断,下标 index=0,位移t=1 左右字符下标则为left=index-t+1 right=index+t,向两边延伸。
代码实现
public class Solution {
public String longestPalindrome(String s) {
//只要一个字符直接返回
if (s.length()==1){
return s;
}
//最长的回文字符串,默认值为第一个字符组成的字符串 例如 2 1 0 1 2
String longest=s.charAt(0)+"";
//取下标1位中心,找两边对称的字符串
for (int i=1,len=s.length();i<len&&len-i>longest.length()/2;i++){
//去中心点位 s[i] 向两边延伸
for (int t=1;t<=i;t++){
//调用函数检查两边第t个位置是否相等
if (check(s,i,t)){
String now=s.substring(i-t,i+t+1);
if (now.length()>longest.length()){
longest=now;
}
}else {
break;
}
}
}
//取第0个位中心,找没有中心字符串且两边对称的 例如 2 1 1 2
for (int i=0,len=s.length();i<len;i++){
//调用函数找出以0为起始位置时最长的回文串
String ret=check(s,i);
if (ret.length()>longest.length()){
longest=ret;
}
}
return longest;
}
public boolean check(String s,int index,int t){
//如果index两边相距t个位置的元素相同则返回true
if (index+t<s.length()&&index-t>-1){
return s.charAt(index-t)==s.charAt(index+t);
}
return false;
}
public String check(String s,int index){
//找出以某个点为起始点,两边最长的回文子串
String longest="";
for (int t=1,len=s.length(),left=index-t+1,right=index+t;left>=0&&right<len;t++,left--,right++){
char leftChar=s.charAt(left);
char rightChar=s.charAt(right);
if (leftChar==rightChar){
longest=s.substring(left,right+1);
}else {
break;
}
}
return longest;
}
public static void main(String[] args) {
System.out.println(new Solution().longestPalindrome("tt"));
}
}