给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
第一种,马拉车算法,
class Solution {
public String longestPalindrome(String s) {
// Insert '#'
String t = "$#";
for (int i = 0; i < s.length(); ++i) {
t += s.charAt(i);
t += "#";
}
t += "@";
// Process t
int[] p = new int[t.length()];;
int mx = 0, id = 0, resLen = 0, resCenter = 0;
for (int i = 1; i < t.length()-1; ++i) {
p[i] = mx > i ? Math.min(p[2 * id - i], mx - i) : 1;
while (((i - p[i])>=0) && ((i + p[i])<t.length()-1) && (t.charAt(i + p[i]) == t.charAt(i - p[i])))
++p[i];
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
if (resLen < p[i]) {
resLen = p[i];
resCenter = i;
}
}
return s.substring((resCenter - resLen) / 2, (resCenter - resLen) / 2 + resLen-1);
}
}
博主也不清楚这是否是马拉车算法,因为耗时有点久,但对于马拉车算法博主还有待理解,所以先暂时不写出来
第二种耗时非常少,也好理解,博主贴出来大家一起学习
class Solution {
public static String longestPalindrome(String s) {
if(s == null || s.length() == 0){
return "";
}
int[] range = new int[2];
char[] str = s.toCharArray();
for(int i = 0 ; i < s.length(); i ++){
i = findLongest(str,i,range);
}
return s.substring(range[0],range[1]+1);
}
public static int findLongest(char[] str, int low, int[] range){
int high = low ;
while (high < str.length - 1 && str[high + 1] == str[low]){
high ++ ;
}
int ans = high;
while (low > 0 && high < str.length - 1 && str[low -1] == str[high + 1]){
low --;
high ++;
}
if(high - low > range[1] - range[0]){
range[0] = low;
range[1] = high;
}
return ans;
}
}
此解法比如pwwwal,先从p开始,先是比较p后面第一位,如果相同,则将high+1,再继续比较第二位,相同再加一,不一样则退出比较,这一次比较后的得到的都是相同字母一定是回文字串,然后第二步,将high+1与low-1进行比较,如果相同,就high+1,low-1,直到不同退出比较,这样就能找到不同字母的回文字串,再从high+1处进行下一轮求回文字串,第三个比较就是求出最长回文字串的坐标,