状态转移方程
flag[i][j] = flag[i + 1][j - 1] && s.charAt(i) == s.charAt(j)
flag[i][j] = true表示从下标i到j的字串是回文串,下标i + 1到j - 1的字串是否是回文串已经判断过了,如果为true且首尾字符相同则这个字串是回文串
动态规划
关键在于递推公式和使用辅助数组,推导一遍过程有助于理解,结合代码食用
代码:
public class Solution {
public String longestPalindrome(String s) {
int len = s.length();
//flag[i][j] = true表示从下标i到j的字串是回文串
boolean[][] flag = new boolean[len][len];
String ans = "";
//从短的字符串递推到长的字符串
for (int l = 0; l < len; l++) {
for (int i = 0; i + l < len; i++) {
//判断这个l + 1长度的字串是否是回文串
int j = i + l;
if(l == 0){
//长度为1的字符串显然是回文串
flag[i][j] = true;
}else if(l == 1){
//长度为2的字符串判断两个字符是否相等
if(s.charAt(i) == s.charAt(j)){
flag[i][j] = true;
}
}else{
//下边i + 1到j - 1的字串是否是回文串已经判断过了,如果为true且首尾字符相同
// 则这个字串是回文串
if(flag[i + 1][j - 1] && s.charAt(i) == s.charAt(j)){
flag[i][j] = true;
}
}
//取最长的结果
if(flag[i][j] && l + 1 > ans.length())
ans = s.substring(i, i + l + 1);
}
}
return ans;
}
public static void main(String[] args) {
Solution solution = new Solution();
String ans = solution.longestPalindrome("babad");
System.out.println(ans);
}
}
暴力解法
两重循环加上判断回文串
public class Solution {
/**
* 暴力枚举法,三重循环
* @param s
* @return
*/
public String longestPalindrome(String s) {
if(s.length() == 1)
return s;
int len = s.length();
int maxlen = 0;
String ans = "";
//最后一个位置没必要枚举了
for (int i = 0; i < len - 1; i++) {
for (int j = i; j < len; j++) {
//进行剪枝操作
if((j - i + 1) > maxlen && judge(s, i, j)){
maxlen = j - i + 1;
ans = s.substring(i, j + 1);
}
}
}
return ans;
}
//判断回文串
public boolean judge(String s,int l,int r){
while(l < r){
if(s.charAt(l) != s.charAt(r)){
return false;
}
l++;
r--;
}
return true;
}
public static void main(String[] args) {
Solution solution = new Solution();
String ans = solution.longestPalindrome("a");
System.out.println(ans);
}
}