给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
思路和代码
动态规划
时间复杂度 O(n²)
空间复杂度O(n²)
动态转移方程 dp[i][j] = dp[i+1][j-1] && s.charAt(i) == s.charAt(j)
class Solution {
private int [] index = new int[2]; // 最长回文串的下标
public String longestPalindrome(String s) {
int len = s.length();
if (len < 1) return "";
boolean[][] dp = new boolean[len][len];
for (int size = 0; size < len; size++){
//size+1表示回文串的长度
for (int i = 0; i + size < len; i++){
if (size <= 1) dp[i][i+size] = (s.charAt(i) == s.charAt(i+size));
else dp[i][i+size] = dp[i+1][i-1+size] && (s.charAt(i) == s.charAt(i+size));
if (dp[i][i+size]){
index[0] = i;
index[1] = i+size;
}
}
}
return s.substring(index[0],index[1]+1);
}
}
中心扩散算法
时间复杂度 O(n²)
空间复杂度O(1)
class Solution {
private int maxLen = 0; // 最长回文串的长度
private int [] index = new int[2]; // 最长回文串的下标
public String longestPalindrome(String s) {
if (s.length() <= 1) return s;
int max = 1;
int len = s.length();
for (int i = 0; i + maxLen / 2 < s.length();i++){
// i + maxLen/2 < s.length() 是一个优化 相当于提前结束循环
centerSpread(s,len,i,i,-1);
centerSpread(s,len,i,i+1,0);
}
return s.substring(index[0],index[1]+1);
}
public void centerSpread(String s,int len,int x,int y,int num){
while (x >= 0 && y < len){
if (s.charAt(x)!=s.charAt(y)) break;
num += 2;
x -= 1;
y += 1;
}
if (num > maxLen){
maxLen = num;
index[0] = x+1;
index[1] = y-1;
}
}
}
Manacher算法
马拉车算法较难 面试一般不会考察 可不用掌握