//中心扩散法,从中间向两边扩散。比动态规划计算量更少。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len < 2){
return s;
}
int maxLen = 1;
int begin = 0;
char[] charArray = s.toCharArray();
for(int i = 0; i < len - 1; i++){
int oddLen = expandAroundCenter(charArray,i,i);
int evenLen = expandAroundCenter(charArray,i, i + 1);
int curMaxLen = Math.max(oddLen, evenLen);
if(curMaxLen > maxLen){
maxLen = curMaxLen;
//这一步需要自己去发现规律
//比如 b a b a b 中的 b a b, i = 1 maxLen= 3 begin = 0 和
//b a a b 中的b a a b,i = 1 maxLen = 4 begin = 0 就可归纳得出规律
begin = i - (maxLen - 1) / 2;
}
}
return s.substring(begin, begin + maxLen);
}
private int expandAroundCenter(char[] charArray, int left, int right){
//当left = right 的时候, 回文中心是一个字符,回文串的长度是奇数
//当 right = left + 1的时候,此时回文中心两个字符,回文串的长度是偶数
int len = charArray.length;
int i = left;
int j = right;
while(i>=0 && j < len){
if(charArray[i] == charArray[j]){
i--;
j++;
} else{
break;
}
}
//回文串的长度是j - i + 1 - 2 = j - i + 1 这个2是i-- 和j++多出来的2
return j - i - 1;
}
}
题解过程:
b a b a b
0 1 2 3 4
首先 0 0 和 0 1 开始 => 0 0 判断相等退出,返回 1 - (-1) - 1 = 1 同理 0 1直接退出,返回 0
其次 1 1 和 1 2 开始 => 1 1 判断相等后扩散 0 2 也相等,返回 3 。同理 1 2返回 0。
其余都类似
最终得到 bab为最长子串,长度为3。
时间复杂度:O(n2)
空间复杂度:O(n2)
//动态规划 => 通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len < 2){
return s;
}
int maxLen = 1;
int begin = 0;
//dp[i][j] 表示 s[i..j] 是否是回文串
boolean[][] dp = new boolean[len][len];
//自己对应的一个字母肯定是回文串
for(int i = 0; i < len; i++){
dp[i][i] = true;
}
char[] charArray = s.toCharArray();
//左下角先填 [0 1] [0 2] [1 2] [0 3] [1 3] [2 3] [....] 竖着先填
for(int j = 1; j < len; j++){
for(int i = 0; i < j; i++){
if(charArray[i] != charArray[j]){
dp[i][j] = false;
} else {
if(j - i < 3){
dp[i][j] = true;
}else {
dp[i][j] = dp[i + 1][j - 1];
}
}
//只要 dp[i][j] == true 成立, 就表示字串 s[i .. j] 是回文,此时记录回文长度和起始位置
if(dp[i][j] && j - i + 1 > maxLen){
maxLen = j - i + 1;
begin = i;
}
}
}
return s.substring(begin, begin + maxLen);
}
}
题解过程:
b a b a b
0 1 2 3 4
首先每一个[i, i]都为true。
0 1 2 3 4
0 T
1 T
2 T
3 T
4 T
对于[0, 1] => [i] != [j], 对于[0, 2] 有 [i] = [j] 且 j - i < 3。其他同理
0 1 2 3 4
0 T F T F
1 T F T F
2 T F T
3 T F
4 T
对于 [0, 4] 则需要用到动态规划, 利用前面的已知信息。首先可知[0] = [4], 且[1,3]为T, 故为T。
0 1 2 3 4
0 T F T F T
1 T F T F
2 T F T
3 T F
4 T
左下角为对称, 最终可得到最大字串。
时间复杂度:O(n2)
空间复杂度:O(n2)