给你一个字符串
s
,找到s
中最长的回文子串。示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2:
输入:s = "cbbd" 输出:"bb"示例 3:
输入:s = "a" 输出:"a"示例 4:
输入:s = "ac" 输出:"a"提示:
1 <= s.length <= 1000
s
仅由数字和英文字母(大写和/或小写)组成
/**
是否是回文?正读反读一样
boolean dp[i][j]={
dp[i][j]=dp[i+1][j-1]且dp[i]==dp[j]
}
**/
class Solution {
public String longestPalindrome(String s) {
int len=s.length();
if(len<2)return s;//空字符串和单字符字符串的回文为本身
char[] str=s.toCharArray();
int max=1,index=0;
boolean[][] dp=new boolean[len][len];
for(int i=0;i<len;i++) {
dp[i][i]=true;
}
/**
自己做了两个从0开始的遍历,出现短字符串还没经历判断的情况
需要先进行短字符串的回文判断遍历,才能根据已有结果判断长字符串是否回文
我是伞兵我是伞兵,重复一遍,我是伞兵
**/
for(int L=2;L<=len;L++){//需要判断的字符串长度遍历
for(int i=0;i<len;i++){//遍历字符串左边界
int j=L+i-1;//获取右边界
if(j>=len)break;//越界
if(str[i]==str[j]){
if(j-i<=2){
dp[i][j]=true;
}else{
dp[i][j]=dp[i+1][j-1];//i+1不会越界,因为i=len的时候,j越界处理了
}
}else{
dp[i][j]=false;
}
if(dp[i][j]&&(j-i+1)>max){
max=j-i+1;
index=i;
}
}
}
return s.substring(index,index+max);
}
}
/**
中心扩展,很符合正常人的思考思路
**/
class Solution {
public String longestPalindrome(String s) {
int max=1,start=0,end=0;
for(int i=0;i<s.length();i++) {
int singleCenter=centerExtend(s,i,i);
int doubleCenter=centerExtend(s,i,i+1);
max=Math.max(singleCenter, doubleCenter);
if(max>end-start) {
start=i-(max-1)/2;//这个前索引的计算要注意
end=i+(max/2)+1;
}
}
return s.substring(start,end);
}
public int centerExtend(String s,int start,int end){
while(start>=0&&end<s.length()&&s.charAt(start)==s.charAt(end)) {
start--;
end++;
}
return end-start-1;
}
}