题目
题解
中心扩散法
主要思想就是从中心往外扩展
- 如果 s [ i + 1 ] . . . s [ j − 1 ] s[i+1]...s[j-1] s[i+1]...s[j−1]是个回文串并且 s [ i ] = = s [ j ] s[i]==s[j] s[i]==s[j],那么 s [ i ] . . . s [ j ] s[i]...s[j] s[i]...s[j]也是个回文串
- 特殊情况:串只有一个或者两个元素
一个元素肯定是个回文串,两个元素如果相等则是个回文串,否则不是 - 总结下来就是下面这个公式:
看公式还是很好理解的,那么具体做法怎么做呢?
- 枚举所有回文子串的中心位置
- 对于奇偶长度回文子串,中心位置可能是一个字符,也有可能是两个相邻的字符,因此都进行列举
class Solution {
public String longestPalindrome(String s) {
if(s.length()<=1)
return s;
int begin=0,max=0;//最长回文串开始下标及最大长度初始化
//枚举中心位置,由于最后一个字符不可能向两边扩散了,所以i最大就到n-2
for(int i=0;i<s.length()-1;i++){
int oddlen=expandAroundCenter(s,i,i);
int evenlen=expandAroundCenter(s,i,i+1);//偶数中心有两个字符
int l=Math.max(oddlen,evenlen);
if(l>max){
max=l;
begin=i-(max-1)/2;//奇偶合并的一个写法,否则要分开讨论
}
}
return s.substring(begin,begin+max);
}
public int expandAroundCenter(String s,int left,int right){
while(left>=0&&right<s.length()){
//往两边扩散一个位置
if(s.charAt(left)==s.charAt(right)){
left--;
right++;
}
//再扩散已经不是回文串了,就退出
else
break;
}
//返回回文子串长度
return right-left-1;
}
}
时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
动态规划法
中心扩散法主要是从中心向两边扩散,而动态规划则是从两边向中心夹,其思想如下:
- 一个回文去掉两头之后,剩下的部分依然是回文
- 如果一个字符串两头字符相等,那么只需要看中间部分是不是回文即可
做法:
- 状态d[i][j]:s[i…j]是否是回文串
- 状态转移方程:
d[i][j] = (s[i]==s[j]) && d[i+1][j-1]
,每一步都利用了前一步的结果 - 边界条件: j − 1 − ( i + 1 ) + 1 < 2 j-1-(i+1)+1<2 j−1−(i+1)+1<2(子串长度小于2)=> j − i < 3 j-i<3 j−i<3,即 j − i + 1 < = 3 j-i+1<=3 j−i+1<=3(子串含有2个或3个字符)
- 初始化:
dp[i][i]=true
示例:字符串为babab
class Solution {
public String longestPalindrome(String s) {
int n=s.length();
if(n<=1)
return s;
int begin=0,max=0;//最长回文串开始下标及最大长度初始化
//初始化dp
boolean[][] dp=new boolean[n][n];//默认是false
for(int i=0;i<n;i++)
dp[i][i]=true;
//右边界j
for(int j=1;j<n;j++){
//左边界i
for(int i=0;i<n;i++){
if(s.charAt(i)!=s.charAt(j))
dp[i][j]=false;
//s[i]==s[j]的情况
else{
if(j-i<3)
dp[i][j]=true;
else
dp[i][j]=dp[i+1][j-1];
}
if(dp[i][j]&&j-i+1>max){
max=j-i+1;
begin=i;
}
}
}
return s.substring(begin,begin+max);
}
}
时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n 2 ) O(n^2) O(n2),不如中心扩散法
马拉车法
非常复杂,知道 时间复杂度和空间复杂度都是 O ( n ) O(n) O(n) 就行了
题外话:呼!终于到20天了!加油!