给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
动态规划
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len < 2){
return s;
}
int maxLen = 1;
int begin = 0;
char [] charArray = s.toCharArray();
boolean [][] dp = new boolean[len][len];
for(int i =0;i<len;++i){
dp[i][i] = true;
}
for(int L = 2 ; L<=len;++L){
for(int i =0;i<len;++i){
int j = i + L - 1;
if(j >= len){
break;
}
if(charArray[i] !=charArray[j]){
dp[i][j] = false;
}else{
if(j - i + 1 <= 3 ){
dp[i][j] = true;
}else{
dp[i][j] = dp[ i + 1][ j - 1 ];
}
}
if(dp[i][j] && j - i + 1 > maxLen ){
maxLen = j - i + 1;
begin = i;
}
}
}
return s.substring(begin,begin+maxLen);
}
}
中心扩散法
首先往左寻找与当期位置相同的字符,直到遇到不相等为止。
然后往右寻找与当期位置相同的字符,直到遇到不相等为止。
最后左右双向扩散,直到左和右不相等。我们用一个 boolean dp[l][r] 表示字符串从 i 到 j 这段是否为回文。试想如果 dp[l][r]=true,我们要判断 dp[l-1][r+1] 是否为回文。只需要判断字符串在(l-1)和(r+1)两个位置是否为相同的字符,是不是减少了很多重复计算。
作者:reedfan
public String longestPalindrome(String s) {
if (s == null || s.length() < 2) {
return s;
}
int strLen = s.length();
int maxStart = 0; //最长回文串的起点
int maxEnd = 0; //最长回文串的终点
int maxLen = 1; //最长回文串的长度
boolean[][] dp = new boolean[strLen][strLen];
for (int r = 1; r < strLen; r++) {
for (int l = 0; l < r; l++) {
if (s.charAt(l) == s.charAt(r) && (r - l + 1 <= 3 || dp[l + 1][r - 1])) {
dp[l][r] = true;
if (r - l + 1 > maxLen) {
maxLen = r - l + 1;
maxStart = l;
maxEnd = r;
}
}
}
}
return s.substring(maxStart, maxEnd + 1);
}