给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
题目解析
动态规划:
根据回文串去掉首尾字符后,仍然为回文串。得到状态转移方程:
这个方程的意思就是说是回文串,且
时
也是回文串,否则
不是回文串。
// 动态规划
public String longestPalindrome(String s){
int n = s.length();
boolean[][] dp = new boolean[n][n];
String s1 = "";
char[] c = s.toCharArray();
for (int l = 0; l < n; l++){
for (int i = 0; i + l< n; i++){
int j = i + l;
if(l == 0){
dp[i][j] = true;
}
else if (l == 1){
dp[i][j] = (c[i] == c[j]);
}else{
dp[i][j] = (c[i] == c[j] && dp[i + 1][j - 1]);
}
if (dp[i][j] && l + 1 > s1.length())
s1 = s.substring(i, j + 1);
}
}
return s1;
}
中心扩展:
找出其中的状态转移链:
{某一边界情况}
直到不再为回文串为止。
// 中心扩展法
public String longe(String s){
if (s == null || s.length() < 1) return "";
int star = 0, end = 0;
for (int i = 0; i < s.length(); i++){
int length1 = expandAroundCenter(s, i, i);
int length2 = expandAroundCenter(s, i, i + 1);
int length = Math.max(length1, length2);
if(length > end - star){
star = i - (length - 1) / 2;
end = i + length / 2;
}
}
return s.substring(star, end + 1);
}
public int expandAroundCenter(String s, int left, int right){
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)){
left--;
right++;
}
return right - left - 1;
}