上次做过一个子序列,而这次题目是子串而且需要返回具体子串是哪个
不过这次我们采用其他的思路。
用类似线性dp的写法,不过我觉得本质仍然是区间dp。
每次找到前面子串是否为回文串,再用一个值来记录最大值。
一个字符串如果是回文串那么它肯定首尾相等且中间是回文串。这俩条件缺一不可。那个中间的字符串是否为回文串就是我们需要记到dp数组里的了。
这样我们就可以用一个dp数组记录下前面串是否为回文,每次判断下当前字符是否与目标字符一致,再判断下中间的字符串是否为回文串。
dp数组的定义:
dp[i][j]: 长度j~i位置的串是否为回文串。
转移方程:
若i-j>3:
dp[i][j] = s[i]==s[j]&&dp[i-1][j+1];
若i-j==2 || i-j ==1:
dp[i][j]= s[i]==s[j];
若i-j == 0:
dp[i][j] = true;
(最后一个情况阔以写到初始化里。减少判断)
class Solution {
public String longestPalindrome(String s) {
if(s.length()==0){
return "";
}
boolean[][] dp = new boolean[s.length()][s.length()];
int maxL = 0,maxR = 0;
for(int i =0;i<s.length();i++){
dp[i][i] = true;
}
for(int i=1;i<dp.length;i++){
char cs = s.charAt(i);
for(int j =i-1;j>=0;j--){
char cp = s.charAt(j);
if(cp==cs){
if(i-j<3){
dp[i][j] = true;
}
else{
dp[i][j] = dp[i-1][j+1];
}
}
if(dp[i][j]){
if(i-j>maxR-maxL){
maxR = i;
maxL = j;
}
}
}
}
return s.substring(maxL,maxR+1);
}
}