题目:
给你一个字符串 s
,找到 s
中最长的回文子串。
解题思路:
本题采用动态规划的思想。我们按照子串长度依次递增的顺序来进行分析,
1. 当子串长度为1的时候,必然为回文串;
2. 当子串长度为2的时候,只要两个字符相等,即为回文串;
3. 当子串长度大于3的时候,如果左右边界的两个字符相等并且去除两个边界的子串为回文串,那么该子串也为回文串。
按照以上思路,我们用一个二维布尔类型的数组dp[i][j]来记录从字符串索引i处到索引j处的子串是否为回文串,
1. 当i > j , 不符合规则,dp[i][j] = false;
2. 当i < j , 是回文串则为true, 不是则为false;
3. 当i == j, 一定为回文串,dp[i][j] = true.
注意:
1. 当左右边界字符不相等的时候,一定不是回文子串;
2. 当左右边界字符相等,且子串长度为<=3的时候,一定为回文子串;
3. 当左右边界字符相等,且子串长度>3的时候,dp[i][j] = dp[i +1][j - 1].
代码示例:
public class LongestPalindrome {
public String longestPalindrome(String s) {
int n = s.length();
if (n < 2)
return s;
boolean dp[][] = new boolean[n][n];
for (int i = 0; i < n; i++)
dp[i][i] = true;
int maxLen = 1, begin = 0;
for (int l = 2; l <= n; l++) {
for (int i = 0; i < n; i++) {
int j = i + l - 1;
if (j >= n) break;
if (s.charAt(i) != s.charAt(j))
dp[i][j] = false;
else {
if (j - i < 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);
}
}