给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
法一:中心扩展法
中心扩展法需要根据对称的是奇数个还是偶数个来进行两次不同的判断。
主要思想就是从任意一个字符串开始,往两边扩散,扩散到不想等,记录下最大的长度。
//中心扩展
public static String zhongxin(String s){
if(s.length() ==1 || s.length() == 0){
return s;
}
char[] ch = s.toCharArray();
int len = s.length();
int max = 1;
int start = 0;
for (int i = 0; i < len; i++) {
int t1 = i - 1,t2 = i + 1;
while(t1 >= 0 && t2 < len && ch[t1] == ch[t2]){
if( t2-t1+1 > max){
max = t2 - t1 + 1;
start = t1;
}
t1--;
t2++;
}
}
for (int i = 0; i < len; i++) {
int t1 = i ,t2 = i + 1;
while(t1 >= 0 && t2 < len && ch[t1] == ch[t2]){
if( t2-t1+1 > max){
max = t2 - t1 + 1;
start = t1;
}
t1--;
t2++;
}
}
return s.substring(start,start+max);
}
法二:动态规划
用一个二维数组来表示是否n(i,j)是否是对称,str(i,j)对称的话,n(i,j)为true;
另外n(i,j)true => n(i+1,j-1) true && str[i] == str[j];
另外用两个标志位记录开始的位置和最长的对称长度。
public static String longestPalindrome(String s) {
if(s.equals("")){
return "";
}
int n = s.length();
int start = 0;
int len = 1;
boolean dp[][] = new boolean[n][n];
for(int i = 0;i < n;i++){
dp[i][i] = true;
if(i< n-1 && s.charAt(i) == s.charAt(i+1)){
dp[i][i+1] = true;
len = 2;
start = i;
}
}
for(int l = 3; l <= n;l++){
for(int i = 0; i< n-l+1;i++){//i小j大
int j = l+i-1;
if(s.charAt(j) == s.charAt(i) && dp[i+1][j-1]){
dp[i][j] = true;
if(j-i+1>len){
len = l;
start = i;
}
}
}
}
return s.substring(start,start+len);
}