用动态规划做。
思路很简单,maintain一个dp的二维数组,里面记录dp[i][j]的状态:true就是从I到j 的子字符串是palindrome。分base和recursive case:base就是substring的长度是1或2,直接比较s[i]和s[j],recursive:如果s[i]等于s[j] 并且s[i+1][j-1]也是palindrome,则设 dp[i][j]为true。同时maintain一个max的数组记录最大长度的palindrome的起始index和结束index。
代码:
class Solution {
public String longestPalindrome(String s) {
if (s.length()<=1) return s;
int length = s.length();
boolean[][] dp = new boolean[length][length];
int[] max = new int[2];
for (int i = length; i > -1; i--){
for (int j =i+1; j < length; j++){
// base case: 1 or 2
if (j - i <= 2){
if (s.charAt(i)==s.charAt(j)) {
dp[i][j]=true;
if (j-i+1 > max[1]-max[0]+1){
max[0]=i;
max[1]=j;
}
}
}
else {
if (s.charAt(i)==s.charAt(j) && dp[i+1][j-1]==true) {
dp[i][j]=true;
if (j-i+1 > max[1]-max[0]+1){
max[0]=i;
max[1]=j;
}
}
}
}
}
return s.substring(max[0], max[1]+1);
}
}
有一个难点:就是遍历的顺序问题,两个重要的点:1. j必须大于i,2. 遍历i的时候要反向遍历,consider:“edcbabcdz”这个例子:"dcbabcd"是palindrome,但如果正向遍历,“cbabc”这个字符串的状态是false,因为还没有遍历到,反向则“cbabc”已经被赋值为true
挺好奇为啥这么慢:40ms,beat 41%, O(n^2)