下图勘误:[1,1],[2,2],[3,3]均为空白。[4,0]为false。原文件找不到了。
动态规划
思路:
一轮遍历,j为右边界,i从左到右向j移动但不重叠,形成[i, j]。
先判断最外层,s[i]是否等于s[j],相等再判断内层是否是回文:
当子串s = [i..j]的长度为2或3时,也就是j - i < 3,判断s是否为回文只需确定 s[i]是否等于s[j],比如aa, aba;
当j - i >= 3,s是否为回文取决于dp[i + 1]是否等于dp[j - 1],
也就是s[i + 1] == s[j - 1] ? ,手动填表即可理解。这就是动态转移方程。
public String longestPalindrome(String s) {
int n = s.length();
if (n == 1) {
return s;
}
boolean[][] dp = new boolean[n][n];
char[] charArray = s.toCharArray();
int ans = 1;
int left = 0;
for (int j = 1; j < n; j++) {
for (int i = 0; i < j; i++) {
if (charArray[i] == charArray[j]) {
if (j - i < 3) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
} else {
dp[i][j] = false;
}
if (dp[i][j] && (j - i + 1) > ans) {
ans = j - i + 1;
left = i;
}
}
}
return s.substring(left, left + ans);
}
注意ans必须初始化为1而不是0,否则当输入示例为 ac时,if (dp[i][j] && (j - i + 1) > ans)不通过,截取的是[0, 0+0),出错。正确的是应该返回 a