题目描述
给定一个字符串s,找到s中的最长回文字串,你可以假设s的最大长度为1000.
输出示例:
输入:"babad"
输出:"bab"
注意:"aba"也是一个有效答案
输入:"cbbd"
输出:"bb"
解题思路分析
使用动态规划的思想,动态规划最重要的是两步:
- 定义状态
这里的“状态”数组是二维数组。dp[l][r]表示子串s[l,r](包括区间左右端点)是否构成回文串,是一个二维布尔型数组。即如果字串s[l,r]是回文串,那么dp[l][r]=true。 - 得到状态转移方程
首先有两点:
1.当子串只包含一个字符时,它一定是个回文子串;
2.当子串包含两个以上字符时:如果s[l,r]是一个回文串,那么dp[l + 1][r - 1]=true
所以状态转移方程就为 dp[l][r] = ((s[l] == s[r]) && ((r - l <= 2) || dp[l + 1][r - 1]))
代码实现
public String longestPalindrome(String s) {
if (s == null || s.length() <= 0) {
return "";
}
int len = s.length();
//状态记录数组
boolean[][] dp = new boolean[len][len];
int max = 1;
String longest = s.substring(0, 1);
for (int r = 1; r < len; r++) {
for (int l = 0; l < r; l++) {
//非常关键的判断状态转移问题
if ((s.charAt(l) == s.charAt(r)) && ((r - l <= 2) || dp[l + 1][r - 1]) {
dp[l][r] = true;
if ((r - l + 1) > max) {
max = r - l + 1;
longest = s.substring(l, r + 1);
}
}
}
}
return longest;
}