该题目考虑使用动态规划来解决,对于动态规划来说,我们通常需要一个状态容器,然后对状态容器进行初始化,之后我们需要找到动态规划的转移方程,状态方程如下所示:
代码执行流程
1. 判断当前字符串的长度,如果字符串的长度为1那么一定是回文串,如果是空串那么没有回文串,返回空,此时返回输入字符串即可;
2. 创建动态规划的初始容器,用于判断dp[i][j]是否是回文串
3. 对状态容器进行初始化
4. 存储两个int型变量,一个用于存储回文串的长度,另一个用于存储起始坐标,因为单串一定是回文串,因此max的初始值为1
5. 开始循环,j遍历整个字符串,i的值需要比j小,因为dp矩阵中存放的是dp[i][j]是否是回文串,i>j不存在物理意义
-首先进行判断,如果i和j位置所在的字符不同直接返回false,因为首尾不同
-如果相同的话就进行判断,当j-i<=2的时候返回true,因为进入该判断时说明i和j的位置字符一定相同,有三种无需继续往下判断的状态,分别是ABA,AA,A,分别对应j-i=2,1,0;
-如果上述判断为false,那么结果就是i+1,j-1,也就是CBABC,C=C判断完了,需要判断BAB是否是子串
-判断结束后,如果max的长度变长了,我们修改起始指针,以及max的长度
6. 返回最终结果
class Solution {
public String longestPalindrome(String s) {
//当s的长度小于等于1,直接返回s,因为长度为1一定是回文串,为0是空串
if(s.length() <= 1)
return s;
//动态规划的状态容器,用来判断dp[i][j]是不是回文子串
boolean[][]dp = new boolean[s.length()][s.length()];
//对状态容器进行初始化,当只有一个字符串的时候一定是回文子串
for (int i = 0; i < s.length(); i++) {
dp[i][i] = true;
}
int max = 1, start = 0;
for(int j = 1; j < s.length(); j++){
//之所以i<j。是因为dp矩阵中存放的是dp[i][j]是否是回文串,i>j不存在物理意义
for(int i = 0; i < j && i < s.length()-1; i++){
//此时首尾不一致,一定是false
if(s.charAt(i) != s.charAt(j))
dp[i][j] = false;
else{
if(j-i<=2)
dp[i][j] = true;
else
dp[i][j] = dp[i+1][j-1];
}
if(dp[i][j] && j-i+1>max){
max = j-i+1;
start = i;
}
}
}
return s.substring(start, start+max);
}
}