一、问题描述:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、我的解法:
我的思路:
先假定回文子串长度为1,然后逐步增加长度,当发现以i为中心的回文子串达到当前长度时,继续增加长度,如果出现连续两个长度都能没达到时,不再增加,因为不可能出现更大长度的子串了。
java代码:
class Solution {
public String longestPalindrome(String s) {
if(1 >= s.length()) return s;
int longest = 1;
String longestPalindrome = s.substring(0,1);
String longestPalindromeTmp = s.substring(0,1);
int longestTmp = 1;
int fir = 0;
for(int i=0; i <= s.length()-longestTmp; i++){
longestPalindromeTmp = s.substring(i,i+longestTmp);
if(this.judgePalind(longestPalindromeTmp)){
longestPalindrome = longestPalindromeTmp;
longest = longestTmp;
i = -1;
longestTmp += 1;
continue;
}
else if (i == s.length()-longestTmp){
if(fir != 0 && fir == longestTmp-1){
break ;
}
else {
fir = longestTmp ;
i = -1;
longestTmp += 1;
continue;
}
}
}
return longestPalindrome;
}
public Boolean judgePalind(String s) {
int lenS = s.length();
for(int i=0; i<=lenS/2-1; i++){
if(s.charAt(i) != s.charAt(lenS-i-1))
return false;
}
return true;
}
}
三、其他解法:
1.中心扩散法
思路是:遍历每一个索引,以这个索引为中心,利用“回文串”中心对称的特点,往两边扩散,看最多能扩散多远。
枚举“中心位置”时间复杂度为 O(N)O(N),从“中心位置”扩散得到“回文子串”的时间复杂度为 O(N)O(N),因此时间复杂度可以降到 O(N^2)O(N^2)。
在这里要注意一个细节:回文串在长度为奇数和偶数的时候,“回文中心”的形式是不一样的。
2.马拉车法
Manacher 算法本质上还是中心扩散法,只不过它使用了类似 KMP 算法的技巧,充分挖掘了已经进行回文判定的子串的特点,在遍历的过程中,记录了已经遍历过的子串的信息,也是典型的以空间换时间思想的体现