5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
提示:
1. 1 <= s.length <= 1000
2. s 仅由数字和英文字母(大写和/或小写)组成
法一:动态规划
对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串 “ababa”,如果我们已经知道“bab” 是回文串,那么“ababa” 一定是回文串,这是因为它的首尾两个字母都是“a”。
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];//存放true或false
String ans = "";//初始化ans
for (int l = 0; l < n; ++l) {
for (int i = 0; i + l < n; ++i) {
int j = i + l;
if (l == 0) {
//如果字串长度为1,则是回文数
dp[i][j] = true;
} else if (l == 1) {
//如果字串长度为2,则判断两个元素是否相等
dp[i][j] = (s.charAt(i) == s.charAt(j));
} else {
//子串长度大于 2时,判断首和尾字符是否相同,且判断s[i+1,j-1]是否时回文子串
dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
}
//最长回文字串
if (dp[i][j] && l + 1 > ans.length()) {
ans = s.substring(i, i + l + 1);
}
}
}
return ans;
}
}
复杂度分析
1. 时间复杂度:O(n^2),其中 n是字符串的长度。动态规划的状态总数为 O(n^2),对于每个状态,我们需要转移的时间为 O(1)。
2. 空间复杂度:O(n^2),即存储动态规划状态需要的空间。
法二:中心扩展算法
我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。
class Solution {
// 主函数
public String longestPalindrome(String s) {
// 记录最长回文串
String res = "";
// 穷举以所有点(奇数一个点,偶数两个点)为中心的回文串
for (int i = 0; i < s.length(); i++) {
// 当回文串是奇数时,由一个中心点向两边扩散
String s1 = palindrome(s, i, i);
// 当回文串是偶数时,由中间的两个中心点向两边扩散
String s2 = palindrome(s, i, i + 1);
// 三元运算符:判断为真时取冒号前面的值,为假时取冒号后面的值
res = res.length() > s1.length() ? res : s1;
res = res.length() > s2.length() ? res : s2;
}
return res;
}
// 辅助函数:寻找回文串
private String palindrome(String s, int left, int right) {
// 在区间 [0, s.length() - 1] 中寻找回文串,防止下标越界
while (left >=0 && right < s.length()) {
// 是回文串时,继续向两边扩散
if (s.charAt(left) == s.charAt(right)) {
left--;
right++;
} else {
break;
}
}
// 循环结束时的条件是 s.charAt(left) != s.charAt(right), 所以正确的区间为 [left + 1, right), 方法 substring(start, end) 区间是 [start, end), 不包含 end
return s.substring(left + 1, right);
}
}
复杂度分析
1. 时间复杂度:O(n^2),其中 n 是字符串的长度。长度为 1 和 2 的回文中心分别有 n 和 n-1 个,每个回文中心最多会向外扩展 O(n)次。
2. 空间复杂度:O(1)。